Skip to content

Commit

Permalink
test(trace-viewer): spawn trace viewer tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ruifigueira committed Jul 26, 2024
1 parent 643d3c3 commit 23a6af8
Show file tree
Hide file tree
Showing 5 changed files with 175 additions and 3 deletions.
4 changes: 4 additions & 0 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -759,6 +759,10 @@ export class Extension implements RunHooks {
this._treeItemSelected(testItem);
}

traceViewerInfoForTest() {
return this._traceViewer()?.infoForTest();
}

private _showTrace(testItem: vscodeTypes.TestItem) {
const traceUrl = (testItem as any)[traceUrlSymbol];
if (traceUrl)
Expand Down
21 changes: 20 additions & 1 deletion src/traceViewer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export class SpawnTraceViewer {
private _traceViewerProcess: ChildProcess | undefined;
private _currentFile?: string;
private _config: TestConfig;
private _serverUrlPrefix?: string;

constructor(vscode: vscodeTypes.VSCode, envProvider: () => NodeJS.ProcessEnv, config: TestConfig) {
this._vscode = vscode;
Expand Down Expand Up @@ -82,6 +83,13 @@ export class SpawnTraceViewer {
this._vscode.window.showErrorMessage(error.message);
this.close();
});
if (this._vscode.isUnderTest) {
traceViewerProcess.stdout?.on('data', data => {
const match = data.toString().match(/Listening on (.*)/);
if (match)
this._serverUrlPrefix = match[1];
});
}
}

checkVersion() {
Expand All @@ -96,14 +104,25 @@ export class SpawnTraceViewer {
return true;
}


close() {
this._traceViewerProcess?.stdin?.end();
this._traceViewerProcess = undefined;
this._currentFile = undefined;
this._serverUrlPrefix = undefined;
}

dispose() {
this.close();
}

infoForTest() {
if (!this._serverUrlPrefix)
return;
return {
type: 'spawn',
serverUrlPrefix: this._serverUrlPrefix,
testConfigFile: this._config.configFile,
traceFile: this.currentFile(),
};
}
}
4 changes: 3 additions & 1 deletion src/vscodeTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,6 @@ export type {
TerminalLink,
} from 'vscode';

export type VSCode = typeof import('vscode');
export type VSCode = typeof import('vscode') & {
isUnderTest?: boolean;
};
135 changes: 135 additions & 0 deletions tests/spawn-trace-viewer.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
/**
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { enableConfigs, expect, selectConfig, selectTestItem, test, traceViewerInfo } from './utils';

test.beforeEach(({ showBrowser }) => {
test.skip(showBrowser);
// prevents spawn trace viewer process from opening in browser
process.env.PWTEST_UNDER_TEST = '1';
});

test.use({ showTrace: true, envRemoteName: 'ssh-remote' });

test('@smoke should open trace viewer', async ({ activate }) => {
const { vscode, testController } = await activate({
'playwright.config.js': `module.exports = { testDir: 'tests' }`,
'tests/test.spec.ts': `
import { test } from '@playwright/test';
test('should pass', async () => {});
`,
});

await testController.run();
await testController.expandTestItems(/test.spec/);
selectTestItem(testController.findTestItems(/pass/)[0]);

await expect.poll(() => traceViewerInfo(vscode)).toMatchObject({
type: 'spawn',
traceFile: expect.stringContaining('pass'),
});
});

test('should change opened file in trace viewer', async ({ activate }) => {
const { vscode, testController } = await activate({
'playwright.config.js': `module.exports = { testDir: 'tests' }`,
'tests/test.spec.ts': `
import { test } from '@playwright/test';
test('one', async () => {});
test('two', async () => {});
`,
});

await testController.run();
await testController.expandTestItems(/test.spec/);

selectTestItem(testController.findTestItems(/one/)[0]);

await expect.poll(() => traceViewerInfo(vscode)).toMatchObject({
type: 'spawn',
traceFile: expect.stringContaining('one'),
});

selectTestItem(testController.findTestItems(/two/)[0]);

await expect.poll(() => traceViewerInfo(vscode)).toMatchObject({
type: 'spawn',
traceFile: expect.stringContaining('two'),
});
});

test('should not open trace viewer if test did not run', async ({ activate }) => {
const { vscode, testController } = await activate({
'playwright.config.js': `module.exports = { testDir: 'tests' }`,
'tests/test.spec.ts': `
import { test } from '@playwright/test';
test('should pass', async () => {});
`,
});

await testController.expandTestItems(/test.spec/);
selectTestItem(testController.findTestItems(/pass/)[0]);

await expect.poll(() => traceViewerInfo(vscode)).toBeUndefined();
});

test('should open new trace viewer when another test config is selected', async ({ activate }) => {
const { vscode, testController } = await activate({
'playwright1.config.js': `module.exports = { testDir: 'tests1' }`,
'playwright2.config.js': `module.exports = { testDir: 'tests2' }`,
'tests1/test.spec.ts': `
import { test } from '@playwright/test';
test('one', () => {});
`,
'tests2/test.spec.ts': `
import { test } from '@playwright/test';
test('one', () => {});
`,
});

await enableConfigs(vscode, ['playwright1.config.js', 'playwright2.config.js']);
await selectConfig(vscode, 'playwright1.config.js');

await testController.expandTestItems(/test.spec/);
const testItems = testController.findTestItems(/one/);
await testController.run(testItems);

selectTestItem(testItems[0]);

await expect.poll(() => traceViewerInfo(vscode)).toMatchObject({
type: 'spawn',
serverUrlPrefix: expect.stringContaining('http'),
testConfigFile: expect.stringContaining('playwright1.config.js'),
});
const serverUrlPrefix1 = traceViewerInfo(vscode);

// closes opened trace viewer
await selectConfig(vscode, 'playwright2.config.js');

await expect.poll(() => traceViewerInfo(vscode)).toBeUndefined();

// opens trace viewer from selected test config
selectTestItem(testItems[0]);

await expect.poll(() => traceViewerInfo(vscode)).toMatchObject({
type: 'spawn',
serverUrlPrefix: expect.stringContaining('http'),
testConfigFile: expect.stringContaining('playwright2.config.js'),
});
const serverUrlPrefix2 = traceViewerInfo(vscode);

expect(serverUrlPrefix2).not.toBe(serverUrlPrefix1);
});
14 changes: 13 additions & 1 deletion tests/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ type ActivateResult = {
type TestFixtures = {
vscode: VSCode,
activate: (files: { [key: string]: string }, options?: { rootDir?: string, workspaceFolders?: [string, any][], env?: Record<string, any> }) => Promise<ActivateResult>;
showTrace: boolean;
envRemoteName?: string;
};

export type WorkerOptions = {
Expand Down Expand Up @@ -114,12 +116,14 @@ export const test = baseTest.extend<TestFixtures, WorkerOptions>({
overridePlaywrightVersion: [undefined, { option: true, scope: 'worker' }],
showBrowser: [false, { option: true, scope: 'worker' }],
vsCodeVersion: [1.86, { option: true, scope: 'worker' }],
showTrace: false,
envRemoteName: undefined,

vscode: async ({ browser, vsCodeVersion }, use) => {
await use(new VSCode(vsCodeVersion, path.resolve(__dirname, '..'), browser));
},

activate: async ({ vscode, showBrowser, overridePlaywrightVersion }, use, testInfo) => {
activate: async ({ vscode, showBrowser, showTrace, envRemoteName, overridePlaywrightVersion }, use, testInfo) => {
const instances: VSCode[] = [];
await use(async (files: { [key: string]: string }, options?: { rootDir?: string, workspaceFolders?: [string, any][], env?: Record<string, any> }) => {
if (options?.workspaceFolders) {
Expand All @@ -134,6 +138,10 @@ export const test = baseTest.extend<TestFixtures, WorkerOptions>({
configuration.update('env', options.env);
if (showBrowser)
configuration.update('reuseBrowser', true);
if (showTrace)
configuration.update('showTrace', true);
if (envRemoteName)
vscode.env.remoteName = envRemoteName;

const extension = new Extension(vscode, vscode.context);
if (overridePlaywrightVersion)
Expand Down Expand Up @@ -222,3 +230,7 @@ export async function singleWebViewByPanelType(vscode: VSCode, viewType: string)
await expect.poll(() => vscode.webViewsByPanelType(viewType)).toHaveLength(1);
return vscode.webViewsByPanelType(viewType)[0];
}

export function traceViewerInfo(vscode: VSCode): { type: 'spawn' | 'embedded', serverUrlPrefix?: string, testConfigFile: string } | undefined {
return vscode.extensions[0].traceViewerInfoForTest();
}

0 comments on commit 23a6af8

Please sign in to comment.