diff --git a/.vscode/launch.json b/.vscode/launch.json index 529b15021..9d7b6a804 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -12,7 +12,7 @@ "runtimeExecutable": "${execPath}", "args": [ "--extensionDevelopmentPath=${workspaceFolder}", - "${workspaceFolder}/../playwright/packages/html-reporter" + "${workspaceFolder}/../playwright/examples/todomvc" ], "outFiles": [ "${workspaceFolder}/out/**/*.js" diff --git a/package.json b/package.json index 125129972..3067a3f94 100644 --- a/package.json +++ b/package.json @@ -114,10 +114,6 @@ "type": "boolean", "default": false, "description": "%configuration.playwright.showTrace%" - }, - "playwright.workspaceSettings": { - "type": "object", - "default": {} } } }, diff --git a/src/extension.ts b/src/extension.ts index 32aaeda95..e21cd53d0 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -43,11 +43,12 @@ type StepInfo = { export async function activate(context: vscodeTypes.ExtensionContext) { // Do not await, quickly run the extension, schedule work. - new Extension(require('vscode')).activate(context); + new Extension(require('vscode'), context).activate(); } export class Extension implements RunHooks { private _vscode: vscodeTypes.VSCode; + private _context: vscodeTypes.ExtensionContext; private _disposables: vscodeTypes.Disposable[] = []; // Global test item map. @@ -77,8 +78,9 @@ export class Extension implements RunHooks { private _commandQueue = Promise.resolve(); overridePlaywrightVersion: number | null = null; - constructor(vscode: vscodeTypes.VSCode) { + constructor(vscode: vscodeTypes.VSCode, context: vscodeTypes.ExtensionContext) { this._vscode = vscode; + this._context = context; this._isUnderTest = !!(this._vscode as any).isUnderTest; this._activeStepDecorationType = this._vscode.window.createTextEditorDecorationType({ isWholeLine: true, @@ -98,7 +100,7 @@ export class Extension implements RunHooks { }); this._settingsModel = new SettingsModel(vscode); - this._models = new TestModelCollection(vscode, this._settingsModel); + this._models = new TestModelCollection(vscode, context); this._reusedBrowser = new ReusedBrowser(this._vscode, this._settingsModel, this._envProvider.bind(this)); this._traceViewer = new TraceViewer(this._vscode, this._settingsModel, this._envProvider.bind(this)); this._testController = vscode.tests.createTestController('playwright', 'Playwright'); @@ -135,9 +137,9 @@ export class Extension implements RunHooks { d?.dispose?.(); } - async activate(context: vscodeTypes.ExtensionContext) { + async activate() { const vscode = this._vscode; - this._settingsView = new SettingsView(vscode, this._settingsModel, this._models, this._reusedBrowser, context.extensionUri); + this._settingsView = new SettingsView(vscode, this._settingsModel, this._models, this._reusedBrowser, this._context.extensionUri); const messageNoPlaywrightTestsFound = this._vscode.l10n.t('No Playwright tests found.'); this._disposables = [ this._debugHighlight, @@ -248,7 +250,7 @@ export class Extension implements RunHooks { fileSystemWatchers.map(w => w.onDidChange(rebuildModelForConfig)); fileSystemWatchers.map(w => w.onDidCreate(rebuildModelForConfig)); fileSystemWatchers.map(w => w.onDidDelete(rebuildModelForConfig)); - context.subscriptions.push(this); + this._context.subscriptions.push(this); } private async _rebuildModels(userGesture: boolean): Promise { diff --git a/src/settingsModel.ts b/src/settingsModel.ts index c27a3b017..b48c23469 100644 --- a/src/settingsModel.ts +++ b/src/settingsModel.ts @@ -40,7 +40,6 @@ export class SettingsModel extends DisposableBase { private _onChange: vscodeTypes.EventEmitter; showBrowser: Setting; showTrace: Setting; - workspaceSettings: Setting; constructor(vscode: vscodeTypes.VSCode) { super(); @@ -50,7 +49,6 @@ export class SettingsModel extends DisposableBase { this.showBrowser = this._createSetting('reuseBrowser'); this.showTrace = this._createSetting('showTrace'); - this.workspaceSettings = this._createSetting('workspaceSettings', true); this.showBrowser.onChange(enabled => { if (enabled && this.showTrace.get()) @@ -62,8 +60,8 @@ export class SettingsModel extends DisposableBase { }); } - private _createSetting(settingName: string, perWorkspace = false): Setting { - const setting = new Setting(this._vscode, settingName, perWorkspace); + private _createSetting(settingName: string): Setting { + const setting = new Setting(this._vscode, settingName); this._disposables.push(setting); this._disposables.push(setting.onChange(() => this._onChange.fire())); this._settings.set(settingName, setting); @@ -83,13 +81,11 @@ export class Setting extends DisposableBase { readonly onChange: vscodeTypes.Event; private _onChange: vscodeTypes.EventEmitter; private _vscode: vscodeTypes.VSCode; - private _perWorkspace: boolean; - constructor(vscode: vscodeTypes.VSCode, settingName: string, perWorkspace: boolean) { + constructor(vscode: vscodeTypes.VSCode, settingName: string) { super(); this._vscode = vscode; this.settingName = settingName; - this._perWorkspace = perWorkspace; this._onChange = new vscode.EventEmitter(); this.onChange = this._onChange.event; @@ -112,12 +108,6 @@ export class Setting extends DisposableBase { async set(value: T) { const configuration = this._vscode.workspace.getConfiguration('playwright'); - if (this._perWorkspace) { - // These are not dispatched :shrug: - configuration.update(this.settingName, value, false); - this._onChange.fire(value); - return; - } const existsInWorkspace = configuration.inspect(this.settingName)?.workspaceValue !== undefined; if (existsInWorkspace) configuration.update(this.settingName, value, false); diff --git a/src/testModel.ts b/src/testModel.ts index b8ba519b6..1786c65b7 100644 --- a/src/testModel.ts +++ b/src/testModel.ts @@ -588,11 +588,11 @@ export class TestModelCollection extends DisposableBase { private _selectedConfigFile: string | undefined; private _didUpdate: vscodeTypes.EventEmitter; readonly onUpdated: vscodeTypes.Event; - private _settingsModel: SettingsModel; + private _context: vscodeTypes.ExtensionContext; - constructor(vscode: vscodeTypes.VSCode, settingsModel: SettingsModel) { + constructor(vscode: vscodeTypes.VSCode, context: vscodeTypes.ExtensionContext) { super(); - this._settingsModel = settingsModel; + this._context = context; this._didUpdate = new vscode.EventEmitter(); this.onUpdated = this._didUpdate.event; } @@ -635,7 +635,7 @@ export class TestModelCollection extends DisposableBase { async addModel(model: TestModel) { this._models.push(model); - const workspaceSettings = this._settingsModel.workspaceSettings.get(); + const workspaceSettings = this._context.workspaceState.get(workspaceStateKey) as WorkspaceSettings || {}; const configSettings = (workspaceSettings.configs || []).find(c => c.relativeConfigFile === path.relative(model.config.workspaceFolder, model.config.configFile)); model.isEnabled = configSettings?.enabled || (this._models.length === 1 && !configSettings); await this._loadModelIfNeeded(model); @@ -652,7 +652,7 @@ export class TestModelCollection extends DisposableBase { if (!model.isEnabled) return; await model._listFiles(); - const workspaceSettings = this._settingsModel.workspaceSettings.get(); + const workspaceSettings = this._context.workspaceState.get(workspaceStateKey) as WorkspaceSettings || {}; const configSettings = (workspaceSettings.configs || []).find(c => c.relativeConfigFile === path.relative(model.config.workspaceFolder, model.config.configFile)); if (configSettings) { let firstProject = true; @@ -727,7 +727,7 @@ export class TestModelCollection extends DisposableBase { projects: model.projects().map(p => ({ name: p.name, enabled: p.isEnabled })), }); } - this._settingsModel.workspaceSettings.set(workspaceSettings); + this._context.workspaceState.update(workspaceStateKey, workspaceSettings); } } @@ -738,6 +738,8 @@ export function projectFiles(project: TestProject): Map(); readonly warnings: string[] = []; readonly errors: string[] = []; - readonly context: { subscriptions: any[]; extensionUri: Uri; }; + readonly context: { subscriptions: any[]; extensionUri: Uri; workspaceState: any }; readonly extensions: any[] = []; private _webviewProviders = new Map(); private _browser: Browser; @@ -850,7 +850,12 @@ export class VSCode { constructor(readonly versionNumber: number, baseDir: string, browser: Browser) { this.version = String(versionNumber); - this.context = { subscriptions: [], extensionUri: Uri.file(baseDir) }; + const workspaceStateStorage = new Map(); + const workspaceState = { + get: (key: string) => workspaceStateStorage.get(key), + update: (key: string, value: any) => workspaceStateStorage.set(key, value) + }; + this.context = { subscriptions: [], extensionUri: Uri.file(baseDir), workspaceState }; this._browser = browser; (globalThis as any).__logForTest = message => this.connectionLog.push(message); const commands = new Map Promise>(); @@ -989,7 +994,6 @@ export class VSCode { 'playwright.env': {}, 'playwright.reuseBrowser': false, 'playwright.showTrace': false, - 'playwright.workspaceSettings': {}, }; this.workspace.getConfiguration = scope => { return { @@ -1011,7 +1015,7 @@ export class VSCode { async activate() { for (const extension of this.extensions) - await extension.activate(this.context); + await extension.activate(); for (const [name, provider] of this._webviewProviders) { const webview: any = {}; diff --git a/tests/utils.ts b/tests/utils.ts index 2f11eacfa..436bfe652 100644 --- a/tests/utils.ts +++ b/tests/utils.ts @@ -135,7 +135,7 @@ export const test = baseTest.extend({ if (showBrowser) configuration.update('reuseBrowser', true); - const extension = new Extension(vscode); + const extension = new Extension(vscode, vscode.context); if (overridePlaywrightVersion) extension.overridePlaywrightVersion = overridePlaywrightVersion;