Skip to content

Commit

Permalink
chore: allow running setup and teardown manually in server mode
Browse files Browse the repository at this point in the history
  • Loading branch information
pavelfeldman committed Apr 2, 2024
1 parent 4f34614 commit 68eb7e3
Show file tree
Hide file tree
Showing 9 changed files with 134 additions and 4 deletions.
10 changes: 10 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,16 @@
"category": "Test",
"command": "pw.extension.toggle.showTrace",
"title": "%contributes.command.pw.extension.toggle.showTrace%"
},
{
"category": "Test",
"command": "pw.extension.command.runGlobalSetup",
"title": "%contributes.command.pw.extension.command.runGlobalSetup%"
},
{
"category": "Test",
"command": "pw.extension.command.runGlobalTeardown",
"title": "%contributes.command.pw.extension.command.runGlobalTeardown%"
}
],
"configuration": {
Expand Down
2 changes: 2 additions & 0 deletions package.nls.fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
"contributes.command.pw.extension.command.closeBrowsers": "Fermer tous les navigateurs",
"contributes.command.pw.extension.command.recordNew": "Enregistrer nouveau",
"contributes.command.pw.extension.command.recordAtCursor": "Enregistrer au niveau du curseur",
"contributes.command.pw.extension.command.runGlobalSetup": "Exécuter la configuration globale",
"contributes.command.pw.extension.command.runGlobalTeardown": "Exécuter le nettoyage global",
"contributes.command.pw.extension.command.toggleModels": "Sélectionner les configurations Playwright",
"contributes.command.pw.extension.toggle.reuseBrowser": "Activer/désactiver la réutilisation du navigateur",
"contributes.command.pw.extension.toggle.showTrace": "Activer/désactiver Playwright Trace Viewer",
Expand Down
3 changes: 2 additions & 1 deletion package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
"contributes.command.pw.extension.command.closeBrowsers": "Close all Playwright browsers",
"contributes.command.pw.extension.command.recordNew": "Record new",
"contributes.command.pw.extension.command.recordAtCursor": "Record at cursor",
"contributes.command.pw.extension.command.selectPlaywrightConfig": "Select Playwright Config",
"contributes.command.pw.extension.command.runGlobalSetup": "Run Global Setup",
"contributes.command.pw.extension.command.runGlobalTeardown": "Run Global Teardown",
"contributes.command.pw.extension.command.toggleModels": "Toggle Playwright Configs",
"contributes.command.pw.extension.toggle.reuseBrowser": "Toggle Playwright Browser Reuse",
"contributes.command.pw.extension.toggle.showTrace": "Toggle Playwright Trace Viewer",
Expand Down
4 changes: 4 additions & 0 deletions package.nls.zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,13 @@
"contributes.command.pw.extension.command.closeBrowsers": "关闭全部 Playwright 浏览器",
"contributes.command.pw.extension.command.recordNew": "录制新用例",
"contributes.command.pw.extension.command.recordAtCursor": "在当前光标处开始录制",
"contributes.command.pw.extension.command.runGlobalSetup": "运行全局设置",
"contributes.command.pw.extension.command.runGlobalTeardown": "运行全局拆卸",
"contributes.command.pw.extension.command.toggleModels": "选择 Playwright 配置",
"contributes.command.pw.extension.toggle.reuseBrowser": "是否复用 Playwright 浏览器",
"contributes.command.pw.extension.toggle.showTrace": "是否显示 Playwright 浏览器的跟踪",
"configuration.playwright.env": "Playwright Test 运行环境变量",
"configuration.playwright.reuseBrowser": "在测试用例间显示并复用 Playwright 浏览器",
"configuration.playwright.showTrace": "显示 Playwright 浏览器的跟踪",
"views.test.pw.extension.settingsView": "Playwright"
}
37 changes: 35 additions & 2 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,14 @@ export class Extension implements RunHooks {
vscode.commands.registerCommand('pw.extension.command.toggleModels', async () => {
this._settingsView.toggleModels();
}),
vscode.commands.registerCommand('pw.extension.command.runGlobalSetup', async () => {
await this._queueGlobalHooks('setup');
this._settingsView.updateActions();
}),
vscode.commands.registerCommand('pw.extension.command.runGlobalTeardown', async () => {
await this._queueGlobalHooks('teardown');
this._settingsView.updateActions();
}),
vscode.workspace.onDidChangeTextDocument(() => {
if (this._completedSteps.size) {
this._completedSteps.clear();
Expand Down Expand Up @@ -324,6 +332,26 @@ export class Extension implements RunHooks {
await this._runQueue;
}

private async _queueGlobalHooks(type: 'setup' | 'teardown'): Promise<reporterTypes.FullResult['status']> {
let result: reporterTypes.FullResult['status'] = 'passed';
this._runQueue = this._runQueue.then(async () => {
result = await this._runGlobalHooks(type);
});
await this._runQueue;
return result;
}

private async _runGlobalHooks(type: 'setup' | 'teardown') {
const request = new this._vscode.TestRunRequest();
const testRun = this._testController.createTestRun(request);
try {
const status = (await this._models.selectedModel()?.runGlobalHooks(type, testRun)) || 'failed';
return status;
} finally {
testRun.end();
}
}

private async _runTests(include: readonly vscodeTypes.TestItem[] | undefined, mode: 'run' | 'debug' | 'watch') {
this._completedSteps.clear();
this._executionLinesChanged();
Expand Down Expand Up @@ -364,8 +392,13 @@ export class Extension implements RunHooks {
}

try {
for (const model of this._models.enabledModels())
await this._runTest(this._testRun, include ? [...include] : [], testItemForGlobalErrors, new Set(), model, mode === 'debug', enqueuedTests.length === 1);
for (const model of this._models.enabledModels()) {
let globalSetupResult: reporterTypes.FullResult['status'] = 'passed';
if (model.canRunGlobalHooks('setup'))
globalSetupResult = await model.runGlobalHooks('setup', this._testRun);
if (globalSetupResult === 'passed')
await this._runTest(this._testRun, include ? [...include] : [], testItemForGlobalErrors, new Set(), model, mode === 'debug', enqueuedTests.length === 1);
}
} finally {
this._activeSteps.clear();
this._executionLinesChanged();
Expand Down
4 changes: 4 additions & 0 deletions src/playwrightTestCLI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ export class PlaywrightTestCLI {
await this._innerSpawn(locations, args, {}, reporter, token);
}

async runGlobalHooks(type: 'setup' | 'teardown', testRun: vscodeTypes.TestRun): Promise<'passed' | 'failed' | 'interrupted' | 'timedout'> {
return 'failed';
}

async runTests(items: vscodeTypes.TestItem[], options: PlaywrightTestRunOptions, reporter: reporterTypes.ReporterV2, token: vscodeTypes.CancellationToken): Promise<void> {
const { locations, parametrizedTestTitle } = this._narrowDownLocations(items);
if (!locations)
Expand Down
32 changes: 32 additions & 0 deletions src/playwrightTestServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,38 @@ export class PlaywrightTestServer {
teleReceiver.dispatch(message);
}

async runGlobalHooks(type: 'setup' | 'teardown', testRun: vscodeTypes.TestRun): Promise<'passed' | 'failed' | 'interrupted' | 'timedout'> {
const testServer = await this._testServer();
if (!testServer)
return 'failed';

const disposable = testServer.onStdio(params => {
if (params.type === 'stdout')
testRun.appendOutput(unwrapString(params).toString().replace(/\n/g, '\r\n'));
if (params.type === 'stderr')
testRun.appendOutput(unwrapString(params).toString().replace(/\n/g, '\r\n'));
});

try {
if (type === 'setup') {
const { status } = await testServer.runGlobalSetup({});
return status;
}
const { status } = await testServer.runGlobalTeardown({});
return status;
} finally {
disposable.dispose();
}
}

async runGlobalTeardown(testRun: vscodeTypes.TestRun): Promise<'passed' | 'failed' | 'interrupted' | 'timedout'> {
const testServer = await this._testServer();
if (!testServer)
return 'failed';
const { status } = await testServer.runGlobalTeardown({});
return status;
}

async runTests(items: vscodeTypes.TestItem[], runOptions: PlaywrightTestRunOptions, reporter: reporterTypes.ReporterV2, token: vscodeTypes.CancellationToken): Promise<void> {
const testServer = await this._testServer();
if (token?.isCancellationRequested)
Expand Down
21 changes: 20 additions & 1 deletion src/settingsView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,20 @@ export class SettingsView extends DisposableBase implements vscodeTypes.WebviewV
text: this._vscode.l10n.t('Close all browsers'),
disabled: !this._reusedBrowser.canClose(),
},
{
command: 'pw.extension.command.runGlobalSetup',
svg: `<svg xmlns="http://www.w3.org/2000/svg" height="48" width="48"></svg>`,
text: this._vscode.l10n.t('Run global setup'),
location: 'projectList',
disabled: !this._models.selectedModel() || !this._models.selectedModel()!.canRunGlobalHooks('setup'),
},
{
command: 'pw.extension.command.runGlobalTeardown',
svg: `<svg xmlns="http://www.w3.org/2000/svg" height="48" width="48"></svg>`,
text: this._vscode.l10n.t('Run global teardown'),
location: 'projectList',
disabled: !this._models.selectedModel() || !this._models.selectedModel()!.canRunGlobalHooks('teardown'),
},
{
command: 'pw.extension.command.toggleModels',
svg: `<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 -960 960 960" width="48"><path d="m388-80-20-126q-19-7-40-19t-37-25l-118 54-93-164 108-79q-2-9-2.5-20.5T185-480q0-9 .5-20.5T188-521L80-600l93-164 118 54q16-13 37-25t40-18l20-127h184l20 126q19 7 40.5 18.5T669-710l118-54 93 164-108 77q2 10 2.5 21.5t.5 21.5q0 10-.5 21t-2.5 21l108 78-93 164-118-54q-16 13-36.5 25.5T592-206L572-80H388Zm48-60h88l14-112q33-8 62.5-25t53.5-41l106 46 40-72-94-69q4-17 6.5-33.5T715-480q0-17-2-33.5t-7-33.5l94-69-40-72-106 46q-23-26-52-43.5T538-708l-14-112h-88l-14 112q-34 7-63.5 24T306-642l-106-46-40 72 94 69q-4 17-6.5 33.5T245-480q0 17 2.5 33.5T254-413l-94 69 40 72 106-46q24 24 53.5 41t62.5 25l14 112Zm44-210q54 0 92-38t38-92q0-54-38-92t-92-38q-54 0-92 38t-38 92q0 54 38 92t92 38Zm0-130Z"/></svg>`,
Expand Down Expand Up @@ -238,8 +252,9 @@ function htmlForWebview(vscode: vscodeTypes.VSCode, extensionUri: vscodeTypes.Ur
${vscode.l10n.t('Show trace viewer')}
</label>
</div>
<div class="separator"></div>
</div>
<div id="projectListActions" class="list"></div>
<div class="separator"></div>
<div id="actions" class="list"></div>
</body>
<script nonce="${nonce}">
Expand Down Expand Up @@ -287,6 +302,8 @@ function htmlForWebview(vscode: vscodeTypes.VSCode, extensionUri: vscodeTypes.Ur
actionsElement.textContent = '';
const configToolbarElement = document.getElementById('configToolbar');
configToolbarElement.textContent = '';
const projectListActions = document.getElementById('projectListActions');
projectListActions.textContent = '';
for (const action of params.actions) {
const actionElement = document.createElement('div');
if (action.disabled)
Expand All @@ -307,6 +324,8 @@ function htmlForWebview(vscode: vscodeTypes.VSCode, extensionUri: vscodeTypes.Ur
label.title = action.title || action.text;
if (action.location === 'configToolbar')
configToolbarElement.appendChild(actionElement);
else if (action.location === 'projectList')
projectListActions.appendChild(actionElement);
else
actionsElement.appendChild(actionElement);
svg.outerHTML = action.svg;
Expand Down
25 changes: 25 additions & 0 deletions src/testModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ export class TestModel {
promise: Promise<void>,
finishedCallback: () => void
} | undefined;
private _ranGlobalSetup = false;

constructor(vscode: vscodeTypes.VSCode, workspaceFolder: string, configFile: string, playwrightInfo: { cli: string, version: number }, options: TestModelOptions) {
this._vscode = vscode;
Expand All @@ -94,6 +95,7 @@ export class TestModel {
this._errorByFile.clear();
this._playwrightTest.reset();
this._watches.clear();
this._ranGlobalSetup = false;
}

projects(): TestProject[] {
Expand Down Expand Up @@ -398,6 +400,29 @@ export class TestModel {
this._didUpdate.fire();
}

canRunGlobalHooks(type: 'setup' | 'teardown') {
if (type === 'setup')
return this._options.settingsModel.useTestServer.get() && !this._ranGlobalSetup;
return this._ranGlobalSetup;
}

async runGlobalHooks(type: 'setup' | 'teardown', testRun: vscodeTypes.TestRun): Promise<reporterTypes.FullResult['status']> {
if (type === 'setup') {
if (this._ranGlobalSetup)
return 'passed';
const status = await this._playwrightTest.runGlobalHooks('setup', testRun);
if (status === 'passed')
this._ranGlobalSetup = true;
return status;
}

if (!this._ranGlobalSetup)
return 'passed';
const status = await this._playwrightTest.runGlobalHooks('teardown', testRun);
this._ranGlobalSetup = false;
return status;
}

async runTests(items: vscodeTypes.TestItem[], reporter: reporterTypes.ReporterV2, token: vscodeTypes.CancellationToken) {
if (token?.isCancellationRequested)
return;
Expand Down

0 comments on commit 68eb7e3

Please sign in to comment.