From d2a8099ea980c4ba234315005305ceeea32b061f Mon Sep 17 00:00:00 2001 From: Max Schmitt Date: Mon, 12 Feb 2024 12:57:50 +0100 Subject: [PATCH] fix: use selected project options for codegen --- package-lock.json | 16 ++++++++-------- package.json | 4 ++-- src/extension.ts | 26 ++++++++++++++++++++++---- src/listTests.d.ts | 9 +++++++-- src/playwrightTest.ts | 1 - src/reusedBrowser.ts | 19 +++++++++++++------ src/testModel.ts | 10 +++++++++- 7 files changed, 61 insertions(+), 24 deletions(-) diff --git a/package-lock.json b/package-lock.json index ab37dbef6..bfa16bc41 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,7 +25,7 @@ "@types/glob": "^8.0.0", "@types/node": "^18.11.9", "@types/stack-utils": "^2.0.1", - "@types/vscode": "1.73.0", + "@types/vscode": "1.86.0", "@types/which": "^2.0.1", "@types/ws": "^8.5.3", "@typescript-eslint/eslint-plugin": "^5.44.0", @@ -40,7 +40,7 @@ "typescript": "^4.9.3" }, "engines": { - "vscode": "^1.73.0" + "vscode": "^1.86.0" } }, "node_modules/@ampproject/remapping": { @@ -824,9 +824,9 @@ "dev": true }, "node_modules/@types/vscode": { - "version": "1.73.0", - "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.73.0.tgz", - "integrity": "sha512-FhkfF7V3fj7S3WqXu7AxFesBLO3uMkdCPJJPbwyZXezv2xJ6xBWHYM2CmkkbO8wT9Fr3KipwxGGOoQRrYq7mHg==", + "version": "1.86.0", + "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.86.0.tgz", + "integrity": "sha512-DnIXf2ftWv+9LWOB5OJeIeaLigLHF7fdXF6atfc7X5g2w/wVZBgk0amP7b+ub5xAuW1q7qP5YcFvOcit/DtyCQ==", "dev": true }, "node_modules/@types/which": { @@ -5144,9 +5144,9 @@ "dev": true }, "@types/vscode": { - "version": "1.73.0", - "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.73.0.tgz", - "integrity": "sha512-FhkfF7V3fj7S3WqXu7AxFesBLO3uMkdCPJJPbwyZXezv2xJ6xBWHYM2CmkkbO8wT9Fr3KipwxGGOoQRrYq7mHg==", + "version": "1.86.0", + "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.86.0.tgz", + "integrity": "sha512-DnIXf2ftWv+9LWOB5OJeIeaLigLHF7fdXF6atfc7X5g2w/wVZBgk0amP7b+ub5xAuW1q7qP5YcFvOcit/DtyCQ==", "dev": true }, "@types/which": { diff --git a/package.json b/package.json index 391b7960d..ebbe5322d 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "url": "https://github.com/microsoft/playwright-vscode/issues" }, "engines": { - "vscode": "^1.73.0" + "vscode": "^1.86.0" }, "categories": [ "Testing" @@ -119,7 +119,7 @@ "@types/glob": "^8.0.0", "@types/node": "^18.11.9", "@types/stack-utils": "^2.0.1", - "@types/vscode": "1.73.0", + "@types/vscode": "1.86.0", "@types/which": "^2.0.1", "@types/ws": "^8.5.3", "@typescript-eslint/eslint-plugin": "^5.44.0", diff --git a/src/extension.ts b/src/extension.ts index bb1cd8d39..3319f234b 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -47,6 +47,8 @@ type TestRunInfo = { request: vscodeTypes.TestRunRequest; }; +const projectSymbol = Symbol('project'); + export async function activate(context: vscodeTypes.ExtensionContext) { // Do not await, quickly run the extension, schedule work. new Extension(require('vscode')).activate(context); @@ -178,18 +180,20 @@ export class Extension { this._reusedBrowser.closeAllBrowsers(); }), vscode.commands.registerCommand('pw.extension.command.recordNew', async () => { - if (!this._models.length) { + const selectedProject = await this._getDefaultTestProject(); + if (!selectedProject) { vscode.window.showWarningMessage(messageNoPlaywrightTestsFound); return; } - await this._reusedBrowser.record(this._models, true); + await this._reusedBrowser.record(selectedProject, true); }), vscode.commands.registerCommand('pw.extension.command.recordAtCursor', async () => { - if (!this._models.length) { + const selectedProject = await this._getDefaultTestProject(); + if (!selectedProject) { vscode.window.showWarningMessage(messageNoPlaywrightTestsFound); return; } - await this._reusedBrowser.record(this._models, false); + await this._reusedBrowser.record(selectedProject, false); }), vscode.workspace.onDidChangeTextDocument(() => { if (this._completedSteps.size) { @@ -336,6 +340,7 @@ export class Extension { const projectTag = this._testTree.projectTag(project); if (!runProfile) { runProfile = this._testController.createRunProfile(`${projectPrefix}${folderName}${path.sep}${configName}`, this._vscode.TestRunProfileKind.Run, this._scheduleTestRunRequest.bind(this, configFile, project.name, false), false, projectTag); + (runProfile as any)[projectSymbol] = project; this._runProfiles.set(keyPrefix + ':run', runProfile); } let debugProfile = this._runProfiles.get(keyPrefix + ':debug'); @@ -345,6 +350,19 @@ export class Extension { } } + private async _getDefaultTestProject(): Promise { + const defaultProjects = Array.from(this._runProfiles.values()).filter(project => project.isDefault).map(project => (project as any)[projectSymbol] as TestProject); + if (defaultProjects.length === 0) + return; + if (defaultProjects.length === 1) + return defaultProjects[0]; + const selectedProject = await this._vscode.window.showQuickPick(defaultProjects.map(project => project.name), { + placeHolder: this._vscode.l10n.t('Select a project to run'), + canPickMany: false, + }); + return selectedProject ? defaultProjects.find(project => project.name === selectedProject) : undefined; + } + private _scheduleTestRunRequest(configFile: string, projectName: string, isDebug: boolean, request: vscodeTypes.TestRunRequest) { // Never run tests concurrently. if (this._testRun) diff --git a/src/listTests.d.ts b/src/listTests.d.ts index 99032a0fd..dd3524620 100644 --- a/src/listTests.d.ts +++ b/src/listTests.d.ts @@ -16,12 +16,17 @@ import type { TestError } from './reporter'; -// This matches the structs in packages/playwright-test/src/runner/runner.ts. +// This matches the structs in packages/playwright/src/runner/runner.ts export type ProjectConfigWithFiles = { name: string; testDir: string; - use: { testIdAttribute?: string }; + use: { + testIdAttribute?: string; + browserName?: string; + contextOptions: Record; + launchOptions: Record; + }; files: string[]; }; diff --git a/src/playwrightTest.ts b/src/playwrightTest.ts index 1aa5ea158..457948b60 100644 --- a/src/playwrightTest.ts +++ b/src/playwrightTest.ts @@ -30,7 +30,6 @@ export type TestConfig = { configFile: string; cli: string; version: number; - testIdAttributeName?: string; }; export interface TestListener { diff --git a/src/reusedBrowser.ts b/src/reusedBrowser.ts index d0611129f..c10aefe64 100644 --- a/src/reusedBrowser.ts +++ b/src/reusedBrowser.ts @@ -308,8 +308,8 @@ export class ReusedBrowser implements vscodeTypes.Disposable { return !this._isRunningTests && !!this._pageCount; } - async record(models: TestModel[], recordNew: boolean) { - if (!this._checkVersion(models[0].config)) + async record(selectedProject: TestProject, recordNew: boolean) { + if (!this._checkVersion(selectedProject.model.config)) return; if (!this.canRecord()) { this._vscode.window.showWarningMessage( @@ -321,7 +321,7 @@ export class ReusedBrowser implements vscodeTypes.Disposable { location: this._vscode.ProgressLocation.Notification, title: 'Playwright codegen', cancellable: true - }, async (progress, token) => this._doRecord(progress, models[0], recordNew, token)); + }, async (progress, token) => this._doRecord(progress, selectedProject, recordNew, token)); } highlight(selector: string) { @@ -355,7 +355,8 @@ export class ReusedBrowser implements vscodeTypes.Disposable { return true; } - private async _doRecord(progress: vscodeTypes.Progress<{ message?: string; increment?: number }>, model: TestModel, recordNew: boolean, token: vscodeTypes.CancellationToken) { + private async _doRecord(progress: vscodeTypes.Progress<{ message?: string; increment?: number }>, selectedProject: TestProject, recordNew: boolean, token: vscodeTypes.CancellationToken) { + const model = selectedProject.model; const startBackend = this._startBackendIfNeeded(model.config); let editor: vscodeTypes.TextEditor | undefined; if (recordNew) @@ -374,7 +375,13 @@ export class ReusedBrowser implements vscodeTypes.Disposable { } try { - await this._backend?.setMode({ mode: 'recording', testIdAttributeName: model.config.testIdAttributeName }); + await this._backend?.setMode({ + mode: 'recording', + testIdAttributeName: selectedProject.testIdAttribute, + browserName: selectedProject.browserName, + launchOptions: selectedProject.launchOptions, + contextOptions: selectedProject.contextOptions, + }); } catch (e) { showExceptionAsUserError(this._vscode, model, e as Error); await this._reset(true); @@ -515,7 +522,7 @@ export class Backend extends EventEmitter { await this._send('navigate', params); } - async setMode(params: { mode: 'none' | 'inspecting' | 'recording', testIdAttributeName?: string }) { + async setMode(params: { mode: 'none' | 'inspecting' | 'recording', testIdAttributeName?: string, browserName?: string, launchOptions?: Record, contextOptions?: Record }) { await this._send('setRecorderMode', params); } diff --git a/src/testModel.ts b/src/testModel.ts index 099c0fe4e..21da0c461 100644 --- a/src/testModel.ts +++ b/src/testModel.ts @@ -62,6 +62,11 @@ export type TestProject = { model: TestModel; isFirst: boolean; files: Map; + + testIdAttribute?: string; + browserName?: string; + contextOptions: Record; + launchOptions: Record; }; export class TestModel { @@ -96,7 +101,6 @@ export class TestModel { for (const file of project.files) files.push(...await resolveSourceMap(file, this._fileToSources, this._sourceToFile)); project.files = files; - this.config.testIdAttributeName = project.use?.testIdAttribute; } const projectsToKeep = new Set(); @@ -123,6 +127,10 @@ export class TestModel { ...projectReport, isFirst, files: new Map(), + browserName: projectReport.use.browserName, + testIdAttribute: projectReport.use.testIdAttribute, + launchOptions: projectReport.use.launchOptions, + contextOptions: projectReport.use.contextOptions, }; this.projects.set(project.name, project); return project;