Skip to content

Commit 50a4ad9

Browse files
authored
chore: pick right launch options for codegen (#624)
1 parent 1c9c3f2 commit 50a4ad9

5 files changed

Lines changed: 98 additions & 58 deletions

File tree

src/extension.ts

Lines changed: 70 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17+
import fs from 'fs';
1718
import path from 'path';
1819
import StackUtils from 'stack-utils';
1920
import { DebugHighlight } from './debugHighlight';
@@ -22,13 +23,13 @@ import * as reporterTypes from './upstream/reporter';
2223
import { ReusedBrowser } from './reusedBrowser';
2324
import { SettingsModel } from './settingsModel';
2425
import { SettingsView } from './settingsView';
25-
import { TestModel, TestModelCollection } from './testModel';
26+
import { TestModel, TestModelCollection, TestProject } from './testModel';
2627
import { configError, disabledProjectName as disabledProject, TestTree } from './testTree';
2728
import { NodeJSNotFoundError, getPlaywrightInfo, stripAnsi, stripBabelFrame, uriToPath } from './utils';
2829
import * as vscodeTypes from './vscodeTypes';
2930
import { WorkspaceChange, WorkspaceObserver } from './workspaceObserver';
3031
import { registerTerminalLinkProvider } from './terminalLinkProvider';
31-
import { ErrorContext, RunHooks, TestConfig } from './playwrightTestTypes';
32+
import { RunHooks, TestConfig, ErrorContext } from './playwrightTestTypes';
3233
import { ansi2html } from './ansi2html';
3334
import { LocatorsView } from './locatorsView';
3435

@@ -185,18 +186,34 @@ export class Extension implements RunHooks {
185186
this._reusedBrowser.closeAllBrowsers();
186187
}),
187188
vscode.commands.registerCommand('pw.extension.command.recordNew', async () => {
188-
if (!this._models.hasEnabledModels()) {
189-
await vscode.window.showWarningMessage(messageNoPlaywrightTestsFound);
189+
const model = this._models.selectedModel();
190+
if (!model)
191+
return vscode.window.showWarningMessage(messageNoPlaywrightTestsFound);
192+
193+
const project = model.enabledProjects()[0];
194+
if (!project)
195+
return vscode.window.showWarningMessage(this._vscode.l10n.t(`Project is disabled in the Playwright sidebar.`));
196+
197+
const file = await this._createFileForNewTest(model, project);
198+
if (!file)
190199
return;
200+
201+
202+
const showBrowser = this._settingsModel.showBrowser.get() ?? false;
203+
try {
204+
await this._settingsModel.showBrowser.set(true);
205+
await this._showBrowserForRecording(file, project);
206+
await this._reusedBrowser.record(model);
207+
} finally {
208+
await this._settingsModel.showBrowser.set(showBrowser);
191209
}
192-
await this._reusedBrowser.record(this._models, true);
193210
}),
194211
vscode.commands.registerCommand('pw.extension.command.recordAtCursor', async () => {
195-
if (!this._models.hasEnabledModels()) {
196-
await vscode.window.showWarningMessage(messageNoPlaywrightTestsFound);
197-
return;
198-
}
199-
await this._reusedBrowser.record(this._models, false);
212+
const model = this._models.selectedModel();
213+
if (!model)
214+
return vscode.window.showWarningMessage(messageNoPlaywrightTestsFound);
215+
216+
await this._reusedBrowser.record(model);
200217
}),
201218
vscode.commands.registerCommand('pw.extension.command.toggleModels', async () => {
202219
this._settingsView.toggleModels();
@@ -662,6 +679,49 @@ export class Extension implements RunHooks {
662679
await this._queueWatchRun(new this._vscode.TestRunRequest(testItems), 'items');
663680
}
664681

682+
private async _createFileForNewTest(model: TestModel, project: TestProject) {
683+
let file;
684+
for (let i = 1; i < 100; ++i) {
685+
file = path.join(project.project.testDir, `test-${i}.spec.ts`);
686+
if (fs.existsSync(file))
687+
continue;
688+
break;
689+
}
690+
if (!file)
691+
return;
692+
693+
await fs.promises.writeFile(file, `import { test, expect } from '@playwright/test';
694+
695+
test('test', async ({ page }) => {
696+
// Recording...
697+
});`);
698+
699+
await model.handleWorkspaceChange({ created: new Set([file]), changed: new Set(), deleted: new Set() });
700+
await model.ensureTests([file]);
701+
702+
const document = await this._vscode.workspace.openTextDocument(file);
703+
const editor = await this._vscode.window.showTextDocument(document);
704+
editor.selection = new this._vscode.Selection(new this._vscode.Position(3, 2), new this._vscode.Position(3, 2 + '// Recording...'.length));
705+
706+
return file;
707+
}
708+
709+
private async _showBrowserForRecording(file: string, project: TestProject) {
710+
const fileItem = this._testTree.testItemForFile(file);
711+
if (!fileItem)
712+
return;
713+
if (fileItem.children.size !== 1)
714+
return;
715+
716+
const testItems = this._testTree.collectTestsInside(fileItem);
717+
const testForProject = testItems.length === 1 ? testItems[0] : testItems.find(t => t.label === project.name);
718+
if (!testForProject)
719+
return;
720+
721+
const request = new this._vscode.TestRunRequest([testForProject], undefined, undefined, false, true);
722+
await this._queueTestRun(request, 'run');
723+
}
724+
665725
private async _updateVisibleEditorItems() {
666726
const files = this._vscode.window.visibleTextEditors.map(e => uriToPath(e.document.uri));
667727
await this._ensureTestsInAllModels(files);

src/reusedBrowser.ts

Lines changed: 5 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ import type { TestConfig } from './playwrightTestTypes';
1818
import type { TestModel, TestModelCollection } from './testModel';
1919
import { createGuid } from './utils';
2020
import * as vscodeTypes from './vscodeTypes';
21-
import path from 'path';
22-
import fs from 'fs';
2321
import { installBrowsers } from './installer';
2422
import { SettingsModel } from './settingsModel';
2523
import { BackendServer, BackendClient } from './backend';
@@ -244,9 +242,8 @@ export class ReusedBrowser implements vscodeTypes.Disposable {
244242
return !this._isRunningTests && !!this._pageCount;
245243
}
246244

247-
async record(models: TestModelCollection, recordNew: boolean) {
248-
const selectedModel = models.selectedModel();
249-
if (!selectedModel || !this._checkVersion(selectedModel.config))
245+
async record(model: TestModel) {
246+
if (!model || !this._checkVersion(model.config))
250247
return;
251248
if (!this.canRecord()) {
252249
void this._vscode.window.showWarningMessage(
@@ -258,7 +255,7 @@ export class ReusedBrowser implements vscodeTypes.Disposable {
258255
location: this._vscode.ProgressLocation.Notification,
259256
title: 'Playwright codegen',
260257
cancellable: true
261-
}, async (progress, token) => this._doRecord(progress, selectedModel, recordNew, token));
258+
}, async (progress, token) => this._doRecord(progress, model, token));
262259
}
263260

264261
async highlight(selector: string) {
@@ -297,20 +294,12 @@ export class ReusedBrowser implements vscodeTypes.Disposable {
297294
return true;
298295
}
299296

300-
private async _doRecord(progress: vscodeTypes.Progress<{ message?: string; increment?: number }>, model: TestModel, recordNew: boolean, token: vscodeTypes.CancellationToken) {
301-
const startBackend = this._startBackendIfNeeded(model.config);
302-
if (recordNew)
303-
await this._createFileForNewTest(model);
304-
await startBackend;
297+
private async _doRecord(progress: vscodeTypes.Progress<{ message?: string; increment?: number }>, model: TestModel, token: vscodeTypes.CancellationToken) {
298+
await this._startBackendIfNeeded(model.config);
305299
this._insertedEditActionCount = 0;
306300

307301
progress.report({ message: 'starting\u2026' });
308302

309-
if (recordNew) {
310-
await this._backend?.resetForReuse();
311-
await this._backend?.navigate({ url: 'about:blank' });
312-
}
313-
314303
// Register early to have this._cancelRecording assigned during re-entry.
315304
const canceledPromise = Promise.race([
316305
new Promise<void>(f => token.onCancellationRequested(f)),
@@ -345,31 +334,6 @@ export class ReusedBrowser implements vscodeTypes.Disposable {
345334
});
346335
}
347336

348-
private async _createFileForNewTest(model: TestModel) {
349-
const project = model.enabledProjects()[0];
350-
if (!project)
351-
return;
352-
let file;
353-
for (let i = 1; i < 100; ++i) {
354-
file = path.join(project.project.testDir, `test-${i}.spec.ts`);
355-
if (fs.existsSync(file))
356-
continue;
357-
break;
358-
}
359-
if (!file)
360-
return;
361-
362-
await fs.promises.writeFile(file, `import { test, expect } from '@playwright/test';
363-
364-
test('test', async ({ page }) => {
365-
// Recording...
366-
});`);
367-
368-
const document = await this._vscode.workspace.openTextDocument(file);
369-
const editor = await this._vscode.window.showTextDocument(document);
370-
editor.selection = new this._vscode.Selection(new this._vscode.Position(3, 2), new this._vscode.Position(3, 2 + '// Recording...'.length));
371-
}
372-
373337
async onWillRunTests(config: TestConfig, debug: boolean) {
374338
if (!this._settingsModel.showBrowser.get() && !debug)
375339
return;

src/testModel.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ export class TestModel extends DisposableBase {
348348
const enabledFiles = this.enabledFiles();
349349
const filesToListTests = inputFiles.filter(f => enabledFiles.has(f) && !this._filesWithListedTests.has(f));
350350
if (!filesToListTests.length)
351-
return;
351+
return this._filesPendingListTests?.promise;
352352

353353
for (const file of filesToListTests)
354354
this._filesWithListedTests.add(file);

tests/codegen.spec.ts

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,33 @@
1717
import { connectToSharedBrowser, expect, test, waitForPage } from './utils';
1818

1919
test('should generate code', async ({ activate }) => {
20+
test.slow();
2021
const { vscode } = await activate({
21-
'playwright.config.js': `module.exports = {}`,
22+
'playwright.config.js': `module.exports = {
23+
projects: [
24+
{
25+
name: 'default',
26+
},
27+
{
28+
name: 'germany',
29+
use: {
30+
locale: 'de-DE',
31+
},
32+
},
33+
]
34+
}`,
2235
});
2336

2437
const webView = vscode.webViews.get('pw.extension.settingsView')!;
38+
await webView.getByRole('checkbox', { name: 'default' }).setChecked(false);
39+
await webView.getByRole('checkbox', { name: 'germany' }).setChecked(true);
2540
await webView.getByText('Record new').click();
26-
await expect.poll(() => vscode.lastWithProgressData).toEqual({ message: 'recording\u2026' });
41+
await expect.poll(() => vscode.lastWithProgressData, { timeout: 0 }).toEqual({ message: 'recording\u2026' });
2742

2843
const browser = await connectToSharedBrowser(vscode);
29-
const page = await waitForPage(browser);
44+
const page = await waitForPage(browser, { locale: 'de-DE' });
3045
await page.locator('body').click();
46+
expect(await page.evaluate(() => navigator.language)).toBe('de-DE');
3147
await expect.poll(() => {
3248
return vscode.window.visibleTextEditors[0]?.edits;
3349
}).toEqual([{

tests/utils.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
import { expect as baseExpect, test as baseTest, Browser, chromium, Page } from '@playwright/test';
17+
import { expect as baseExpect, test as baseTest, Browser, BrowserContextOptions, chromium, Page } from '@playwright/test';
1818
// @ts-ignore
1919
import { Extension } from '../out/extension';
2020
import { TestController, VSCode, WorkspaceFolder, TestRun, TestItem } from './mock/vscode';
@@ -197,10 +197,10 @@ export async function connectToSharedBrowser(vscode: VSCode) {
197197
return await chromium.connect(wsEndpoint);
198198
}
199199

200-
export async function waitForPage(browser: Browser) {
200+
export async function waitForPage(browser: Browser, params?: BrowserContextOptions) {
201201
let pages: Page[] = [];
202202
await expect.poll(async () => {
203-
const context = await (browser as any)._newContextForReuse();
203+
const context = await (browser as any)._newContextForReuse(params);
204204
pages = context.pages();
205205
return pages.length;
206206
}).toBeTruthy();

0 commit comments

Comments
 (0)