From 009bbe105a6455d668f1bf78c7590f270032e7c5 Mon Sep 17 00:00:00 2001 From: Rui Figueira Date: Tue, 11 Jun 2024 03:10:33 +0100 Subject: [PATCH] wip: only enable embedded trace viewer on recent playwright test versions TODO: replace playwright version with correct release version --- src/settingsView.ts | 7 ++++++- src/traceViewer.ts | 20 ++++++++++++++------ tests/settings.spec.ts | 1 + tests/trace-viewer.spec.ts | 33 +++++++++++++++++++++++++++++++++ 4 files changed, 54 insertions(+), 7 deletions(-) diff --git a/src/settingsView.ts b/src/settingsView.ts index 8d93635ec..c7ae4b719 100644 --- a/src/settingsView.ts +++ b/src/settingsView.ts @@ -18,6 +18,7 @@ import { DisposableBase } from './disposableBase'; import type { ReusedBrowser } from './reusedBrowser'; import type { SettingsModel } from './settingsModel'; import type { TestModelCollection } from './testModel'; +import { kEmbeddedMinVersion } from './traceViewer'; import { getNonce } from './utils'; import * as vscodeTypes from './vscodeTypes'; import path from 'path'; @@ -28,6 +29,7 @@ type ConfigEntry = { selected: boolean; enabled: boolean; projects: ProjectEntry[]; + embeddedEnabled: boolean; }; type ProjectEntry = { @@ -201,6 +203,7 @@ export class SettingsView extends DisposableBase implements vscodeTypes.WebviewV selected: model === this._models.selectedModel(), enabled: model.isEnabled, projects: model.projects().map(p => ({ name: p.name, enabled: p.isEnabled })), + embeddedEnabled: model.config.version >= kEmbeddedMinVersion, }); } @@ -319,9 +322,11 @@ function htmlForWebview(vscode: vscodeTypes.VSCode, extensionUri: vscodeTypes.Ur } function updateEmbedTraceViewer() { + const enabled = !!selectConfig?.embeddedEnabled; + const embedTraceViewerLabel = document.getElementById('embedTraceViewerLabel'); const showTrace = document.querySelector('[setting="showTrace"]'); - if (showTrace.checked) + if (enabled && showTrace.checked) embedTraceViewerLabel.classList.remove('hidden'); else embedTraceViewerLabel.classList.add('hidden'); diff --git a/src/traceViewer.ts b/src/traceViewer.ts index 8a182eec0..3b850ee16 100644 --- a/src/traceViewer.ts +++ b/src/traceViewer.ts @@ -21,6 +21,9 @@ import { escapeAttribute, findNode, getNonce } from './utils'; import * as vscodeTypes from './vscodeTypes'; import { DisposableBase } from './disposableBase'; +// TODO match with playwright version that includes this feature +export const kEmbeddedMinVersion = 1.46; + function getPath(uriOrPath: string | vscodeTypes.Uri) { return typeof uriOrPath === 'string' ? uriOrPath : @@ -204,7 +207,7 @@ export class TraceViewer implements vscodeTypes.Disposable { await this._startIfNeeded(config); this._currentFile = file; this._traceViewerProcess?.stdin?.write(getPath(file) + '\n'); - this._maybeOpenEmbeddedTraceViewer(); + this._maybeOpenEmbeddedTraceViewer(config); } dispose() { @@ -224,9 +227,9 @@ export class TraceViewer implements vscodeTypes.Disposable { allArgs.push('--host', '0.0.0.0'); allArgs.push('--port', '0'); } - if (embedded) { + if (embedded && this._checkEmbeddedVersion(config)) { allArgs.push('--server-only'); - this._maybeOpenEmbeddedTraceViewer(); + this._maybeOpenEmbeddedTraceViewer(config); } const traceViewerProcess = spawn(node, allArgs, { @@ -265,8 +268,8 @@ export class TraceViewer implements vscodeTypes.Disposable { }); } - private _maybeOpenEmbeddedTraceViewer() { - if (this._traceViewerView || !this._settingsModel.embedTraceViewer.get()) return; + private _maybeOpenEmbeddedTraceViewer(config: TestConfig) { + if (this._traceViewerView || !this._settingsModel.embedTraceViewer.get() || !this._checkEmbeddedVersion(config)) return; this._traceViewerView = new TraceViewerView(this._vscode, this._extensionUri, this._traceViewerUrl); this._traceViewerView.onDispose(() => { this._traceViewerView = undefined; @@ -278,15 +281,20 @@ export class TraceViewer implements vscodeTypes.Disposable { config: TestConfig, message: string = this._vscode.l10n.t('this feature') ): boolean { + const version = 1.35; if (config.version < 1.35) { this._vscode.window.showWarningMessage( - this._vscode.l10n.t('Playwright v1.35+ is required for {0} to work, v{1} found', message, config.version) + this._vscode.l10n.t('Playwright v{0}+ is required for {1} to work, v{2} found', version, message, config.version) ); return false; } return true; } + private _checkEmbeddedVersion(config: TestConfig): boolean { + return config.version >= kEmbeddedMinVersion; + } + async close() { this._traceViewerProcess?.stdin?.end(); this._traceViewerProcess = undefined; diff --git a/tests/settings.spec.ts b/tests/settings.spec.ts index 03c145b2e..2eebfac8c 100644 --- a/tests/settings.spec.ts +++ b/tests/settings.spec.ts @@ -140,5 +140,6 @@ test('should not have Content Security Policy violations', async ({ activate }) const webView = vscode.webViews.get('pw.extension.settingsView')!; await webView.getByLabel('Show browser').click(); + // ensure there's no CSP errors expect(vscode.consoleErrors).toHaveLength(0); }); diff --git a/tests/trace-viewer.spec.ts b/tests/trace-viewer.spec.ts index 8eacde17b..45f46c272 100644 --- a/tests/trace-viewer.spec.ts +++ b/tests/trace-viewer.spec.ts @@ -14,6 +14,7 @@ * limitations under the License. */ +import { describe } from 'node:test'; import { expect, test } from './utils'; test('should show embedded setting only when Show trace viewer setting is enabled', async ({ activate }) => { @@ -83,6 +84,8 @@ test('should show tracer when test runs', async ({ activate }) => { /Before Hooks[\d.]+m?s/, /After Hooks[\d.]+m?s/, ]); + + // ensure there's no CSP errors expect(vscode.consoleErrors).toHaveLength(0); }); @@ -139,3 +142,33 @@ test('should toggle between dark and light themes', async ({ activate }) => { await configuration.update('colorTheme', 'Dark Modern', true); await expect(webview.frameLocator('iframe').locator('body')).toHaveClass('dark-mode'); }); + +describe('playwright older version', () => { + test.use({ overridePlaywrightVersion: 1.44 }); + + test('should hide embedded in older @playwright/test projects', 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 vscode.commands.executeCommand('pw.extension.toggle.embedTraceViewer'); + const configuration = vscode.workspace.getConfiguration('playwright'); + + const settingsView = vscode.webViews.get('pw.extension.settingsView')!; + expect(configuration.get('showTrace')).toBe(true); + expect(configuration.get('embedTraceViewer')).toBe(true); + await expect(settingsView.getByLabel('Show trace viewer')).toBeVisible(); + await expect(settingsView.getByLabel('Embedded')).not.toBeVisible(); + + await testController.expandTestItems(/test.spec/); + const testItems = testController.findTestItems(/pass/); + await testController.run(testItems); + + const [webview] = await vscode.webViewsByPanelType('playwright.traceviewer.view'); + expect(webview).toBeUndefined(); + }); +})