Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test(trace-viewer): add trace viewer info for test
Browse files Browse the repository at this point in the history
Also, converted testItem.selected into a util function to follow the current tests pattern
ruifigueira committed Jul 3, 2024
1 parent b6108e0 commit 4dc39ac
Showing 7 changed files with 61 additions and 21 deletions.
8 changes: 8 additions & 0 deletions src/extension.ts
Original file line number Diff line number Diff line change
@@ -767,6 +767,14 @@ export class Extension implements RunHooks {
return this._reusedBrowser.browserServerWSEndpoint();
}

fireTreeItemSelectedForTest(testItem: vscodeTypes.TestItem | null) {
this._treeItemSelected(testItem);
}

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

private _showTrace(testItem: vscodeTypes.TestItem) {
const traceUrl = (testItem as any)[traceUrlSymbol];
if (traceUrl)
22 changes: 22 additions & 0 deletions src/traceViewer.ts
Original file line number Diff line number Diff line change
@@ -40,6 +40,7 @@ export class SpawnTraceViewer extends DisposableBase {
private _traceViewerProcess: ChildProcess | undefined;
private _settingsModel: SettingsModel;
private _config: TestConfig;
private _serverUrlPrefix?: string;

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

checkVersion() {
@@ -130,6 +138,13 @@ export class SpawnTraceViewer extends DisposableBase {
this._traceViewerProcess?.stdin?.end();
this._traceViewerProcess = undefined;
}

infoForTest() {
return {
type: 'spawn',
serverUrlPrefix: this._serverUrlPrefix,
};
}
}

export class EmbeddedTraceViewer extends DisposableBase {
@@ -234,6 +249,13 @@ export class EmbeddedTraceViewer extends DisposableBase {
}
return true;
}

infoForTest() {
return {
type: 'embedded',
serverUrlPrefix: this._serverUrlPrefix,
};
}
}

class EmbeddedTraceViewerPanel extends DisposableBase {
4 changes: 3 additions & 1 deletion src/vscodeTypes.ts
Original file line number Diff line number Diff line change
@@ -57,4 +57,6 @@ export type {
TerminalLink,
} from 'vscode';

export type VSCode = typeof import('vscode');
export type VSCode = typeof import('vscode') & {
isUnderTest?: boolean;
};
9 changes: 1 addition & 8 deletions tests/mock/vscode.ts
Original file line number Diff line number Diff line change
@@ -185,7 +185,7 @@ export class WorkspaceFolder {
}
}

class TestItem {
export class TestItem {
readonly children = this;
readonly map = new Map<string, TestItem>();
range: Range | undefined;
@@ -209,13 +209,6 @@ class TestItem {
return this.map[Symbol.iterator]();
}

selected() {
const extension = this.testController.vscode.extensions.find(e => e._treeItemSelected);
if (!extension)
throw new Error(`No extension found with _treeItemSelected function`);
extension._treeItemSelected(this);
}

async expand() {
if (this.canResolveChildren)
await this.testController.resolveHandler(this);
8 changes: 6 additions & 2 deletions tests/trace-viewer-legacy.spec.ts
Original file line number Diff line number Diff line change
@@ -14,7 +14,7 @@
* limitations under the License.
*/

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

test.beforeEach(({ showBrowser, overridePlaywrightVersion }) => {
test.skip(!overridePlaywrightVersion || showBrowser);
@@ -38,5 +38,9 @@ test('should fallback to spawn trace viewer in older @playwright/test projects',
await testController.run(testItems);

await expect.poll(() => vscode.warnings).toContain('Playwright v1.46+ is required for embedded trace viewer to work, v1.43 found');
// TODO intercept /Listening on http:\/\/[^:]+:\d+/

await expect.poll(() => traceViewerInfo(vscode)).toMatchObject({
type: 'spawn',
serverUrlPrefix: expect.stringMatching(/http:\/\/0.0.0.0:\d+/),
});
});
21 changes: 12 additions & 9 deletions tests/trace-viewer.spec.ts
Original file line number Diff line number Diff line change
@@ -14,7 +14,7 @@
* limitations under the License.
*/

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

test.beforeEach(({ showBrowser, overridePlaywrightVersion }) => {
test.skip(!!overridePlaywrightVersion || showBrowser);
@@ -68,10 +68,10 @@ test('should switch trace when selected test item changes', async ({ activate })

const webview = await vscode.singleWebViewByPanelType('playwright.traceviewer.view')!;

testItems[0].selected();
selectTestItem(testItems[0]);
await expect(webview.frameLocator('iframe').frameLocator('iframe.snapshot-visible').locator('h1')).toHaveText('Test 1');

testItems[1].selected();
selectTestItem(testItems[0]);
await expect(webview.frameLocator('iframe').frameLocator('iframe.snapshot-visible').locator('h1')).toHaveText('Test 2');
});

@@ -119,7 +119,7 @@ test('should reopen trace viewer if closed', async ({ activate }) => {
await webview.close();
await expect.poll(() => vscode.webViewsByPanelType('playwright.traceviewer.view')).toHaveLength(0);

testItems[0].selected();
selectTestItem(testItems[0]);
await expect.poll(() => vscode.webViewsByPanelType('playwright.traceviewer.view')).toHaveLength(1);
});

@@ -217,7 +217,7 @@ test('should change trace viewer when test config changes', async ({ activate })

const webview = await vscode.singleWebViewByPanelType('playwright.traceviewer.view')!;

testItems[0].selected();
selectTestItem(testItems[0]);
serverUrl1 = await webview.locator('iframe').getAttribute('src') ?? '';
}

@@ -236,7 +236,7 @@ test('should change trace viewer when test config changes', async ({ activate })

const webview = await vscode.singleWebViewByPanelType('playwright.traceviewer.view')!;

testItems[0].selected();
selectTestItem(testItems[0]);
serverUrl2 = await webview.locator('iframe').getAttribute('src') ?? '';
}

@@ -255,7 +255,7 @@ test('should not open trace viewer if selected test item did not run', async ({
await testController.expandTestItems(/test.spec/);
const testItems = testController.findTestItems(/pass/);

testItems[0].selected();
selectTestItem(testItems[0]);

// wait to ensure no async webview is opened
await new Promise(f => setTimeout(f, 1000));
@@ -286,7 +286,7 @@ test('should not open trace viewer if selected test item has no trace', async ({
`);

await configuration.update('showTrace', true, true);
testItems[0].selected();
selectTestItem(testItems[0]);

// wait to ensure no async webview is opened
await new Promise(f => setTimeout(f, 1000));
@@ -321,5 +321,8 @@ test('should fallback to spawn trace viewer if embedded not enabled', async ({ a
await expect.poll(() => vscode.webViewsByPanelType('playwright.traceviewer.view')).toHaveLength(0);
expect(vscode.warnings).toHaveLength(0);

// TODO intercept /Listening on http:\/\/[^:]+:\d+/
await expect.poll(() => traceViewerInfo(vscode)).toMatchObject({
type: 'spawn',
serverUrlPrefix: expect.stringMatching(/http:\/\/0.0.0.0:\d+/),
});
});
10 changes: 9 additions & 1 deletion tests/utils.ts
Original file line number Diff line number Diff line change
@@ -16,7 +16,7 @@

import { expect as baseExpect, test as baseTest, Browser, chromium, Page } from '@playwright/test';
import { Extension } from '../out/extension';
import { TestController, VSCode, WorkspaceFolder, TestRun } from './mock/vscode';
import { TestController, VSCode, WorkspaceFolder, TestRun, TestItem } from './mock/vscode';

import path from 'path';

@@ -225,3 +225,11 @@ function escapeRegex(text: string) {
}

export const escapedPathSep = escapeRegex(path.sep);

export async function selectTestItem(testItem: TestItem) {
testItem.testController.vscode.extensions[0].fireTreeItemSelectedForTest(testItem);
}

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

0 comments on commit 4dc39ac

Please sign in to comment.