diff --git a/src/backend.ts b/src/backend.ts index 6dc33dfe1..a3528b76b 100644 --- a/src/backend.ts +++ b/src/backend.ts @@ -124,7 +124,7 @@ export class BackendClient extends EventEmitter { requestGracefulTermination() { } - protected send(method: string, params: any = {}): Promise { + send(method: string, params: any = {}): Promise { return new Promise((fulfill, reject) => { const id = ++BackendClient._lastId; const command = { id, guid: 'DebugController', method, params, metadata: {} }; @@ -132,4 +132,8 @@ export class BackendClient extends EventEmitter { this._callbacks.set(id, { fulfill, reject }); }); } + + close() { + this._transport.close(); + } } diff --git a/src/extension.ts b/src/extension.ts index bb1cd8d39..ce72d0161 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -19,7 +19,7 @@ import StackUtils from 'stack-utils'; import { DebugHighlight } from './debugHighlight'; import { installBrowsers, installPlaywright } from './installer'; import { MultiMap } from './multimap'; -import { PlaywrightTest, TestListener } from './playwrightTest'; +import { PlaywrightTest, RunHooks, TestConfig, TestListener } from './playwrightTest'; import type { Location, TestError, Entry } from './oopReporter'; import { ReusedBrowser } from './reusedBrowser'; import { SettingsModel } from './settingsModel'; @@ -42,9 +42,8 @@ type StepInfo = { }; type TestRunInfo = { - selectedProjects: TestProject[]; - isDebug: boolean; - request: vscodeTypes.TestRunRequest; + project: TestProject; + include: readonly vscodeTypes.TestItem[] | undefined; }; export async function activate(context: vscodeTypes.ExtensionContext) { @@ -52,7 +51,7 @@ export async function activate(context: vscodeTypes.ExtensionContext) { new Extension(require('vscode')).activate(context); } -export class Extension { +export class Extension implements RunHooks { private _vscode: vscodeTypes.VSCode; private _disposables: vscodeTypes.Disposable[] = []; @@ -73,7 +72,7 @@ export class Extension { private _activeStepDecorationType: vscodeTypes.TextEditorDecorationType; private _completedStepDecorationType: vscodeTypes.TextEditorDecorationType; private _playwrightTest: PlaywrightTest; - private _projectsScheduledToRun: TestProject[] | undefined; + private _itemsScheduledToRun: TestRunInfo[] | undefined; private _debugHighlight: DebugHighlight; private _isUnderTest: boolean; private _reusedBrowser: ReusedBrowser; @@ -112,7 +111,7 @@ export class Extension { this._settingsModel = new SettingsModel(vscode); this._reusedBrowser = new ReusedBrowser(this._vscode, this._settingsModel, this._envProvider.bind(this)); this._traceViewer = new TraceViewer(this._vscode, this._settingsModel, this._envProvider.bind(this)); - this._playwrightTest = new PlaywrightTest(this._vscode, this._settingsModel, this._reusedBrowser, this._isUnderTest, this._envProvider.bind(this)); + this._playwrightTest = new PlaywrightTest(this._vscode, this._settingsModel, this, this._isUnderTest, this._envProvider.bind(this)); this._testController = vscode.tests.createTestController('pw.extension.testController', 'Playwright'); this._testController.resolveHandler = item => this._resolveChildren(item); this._testController.refreshHandler = () => this._rebuildModel(true).then(() => {}); @@ -127,6 +126,17 @@ export class Extension { this._treeItemObserver = new TreeItemObserver(this._vscode); } + async onWillRunTests(config: TestConfig, debug: boolean) { + await this._reusedBrowser.onWillRunTests(config, debug); + return { + connectWsEndpoint: this._reusedBrowser.browserServerWSEndpoint(), + }; + } + + async onDidRunTests(debug: boolean) { + await this._reusedBrowser.onDidRunTests(debug); + } + reusedBrowserForTest(): ReusedBrowser { return this._reusedBrowser; } @@ -205,7 +215,7 @@ export class Extension { ...Object.values(this._diagnostics), this._treeItemObserver, ]; - await this._rebuildModel(true); + await this._rebuildModel(false); const fileSystemWatchers = [ // Glob parser does not supported nested group, hence multiple watchers. @@ -334,13 +344,14 @@ export class Extension { const keyPrefix = configFile + ':' + project.name; let runProfile = this._runProfiles.get(keyPrefix + ':run'); const projectTag = this._testTree.projectTag(project); + const isDefault = false; if (!runProfile) { - runProfile = this._testController.createRunProfile(`${projectPrefix}${folderName}${path.sep}${configName}`, this._vscode.TestRunProfileKind.Run, this._scheduleTestRunRequest.bind(this, configFile, project.name, false), false, projectTag); + runProfile = this._testController.createRunProfile(`${projectPrefix}${folderName}${path.sep}${configName}`, this._vscode.TestRunProfileKind.Run, this._scheduleTestRunRequest.bind(this, configFile, project.name, false), isDefault, projectTag); this._runProfiles.set(keyPrefix + ':run', runProfile); } let debugProfile = this._runProfiles.get(keyPrefix + ':debug'); if (!debugProfile) { - debugProfile = this._testController.createRunProfile(`${projectPrefix}${folderName}${path.sep}${configName}`, this._vscode.TestRunProfileKind.Debug, this._scheduleTestRunRequest.bind(this, configFile, project.name, true), false, projectTag); + debugProfile = this._testController.createRunProfile(`${projectPrefix}${folderName}${path.sep}${configName}`, this._vscode.TestRunProfileKind.Debug, this._scheduleTestRunRequest.bind(this, configFile, project.name, true), isDefault, projectTag); this._runProfiles.set(keyPrefix + ':debug', debugProfile); } } @@ -362,42 +373,43 @@ export class Extension { // VSCode will issue several test run requests (one per enabled run profile). Sometimes // these profiles belong to the same config and we only want to run tests once per config. // So we collect all requests and sort them out in the microtask. - if (!this._projectsScheduledToRun) { - this._projectsScheduledToRun = []; - this._projectsScheduledToRun.push(project); + if (!this._itemsScheduledToRun) { + this._itemsScheduledToRun = []; + this._itemsScheduledToRun.push({ project, include: request.include }); // Make sure to run tests outside of this function's control flow // so that we can create a new TestRunRequest and see its output. // TODO: remove once this is fixed in VSCode (1.78?) and we // can see test output without this hack. setTimeout(async () => { - const selectedProjects = this._projectsScheduledToRun; - this._projectsScheduledToRun = undefined; - if (selectedProjects) - await this._runMatchingTests({ selectedProjects, isDebug, request }); + const selectedItems = this._itemsScheduledToRun; + this._itemsScheduledToRun = undefined; + if (selectedItems) + await this._runMatchingTests(selectedItems, isDebug ? 'debug' : 'run'); }, 520); } else { // Subsequent requests will return right away. - this._projectsScheduledToRun.push(project); + this._itemsScheduledToRun.push({ project, include: request.include }); } } - private async _runMatchingTests(testRunInfo: TestRunInfo) { - const { selectedProjects, isDebug, request } = testRunInfo; - + private async _runMatchingTests(testRunInfos: TestRunInfo[], mode: 'run' | 'debug') { this._completedSteps.clear(); this._executionLinesChanged(); + const projects = testRunInfos.map(info => info.project); + const include = testRunInfos.map(info => info.include || []).flat(); + // Create a test run that potentially includes all the test items. // This allows running setup tests that are outside of the scope of the // selected test items. const rootItems: vscodeTypes.TestItem[] = []; this._testController.items.forEach(item => rootItems.push(item)); - const requestWithDeps = new this._vscode.TestRunRequest(rootItems, [], request.profile); + const requestWithDeps = new this._vscode.TestRunRequest(rootItems, [], undefined); // Global errors are attributed to the first test item in the request. // If the request is global, find the first root test item (folder, file) that has // children. It will be reveal with an error. - let testItemForGlobalErrors = request.include?.[0]; + let testItemForGlobalErrors = include[0]; if (!testItemForGlobalErrors) { for (const rootItem of rootItems) { if (!rootItem.children.size) @@ -414,7 +426,7 @@ export class Extension { const enqueuedTests: vscodeTypes.TestItem[] = []; // Provisionally mark tests (not files and not suits) as enqueued to provide immediate feedback. - for (const item of request.include || []) { + for (const item of include) { for (const test of this._testTree.collectTestsInside(item)) { this._testRun.enqueued(test); enqueuedTests.push(test); @@ -423,7 +435,7 @@ export class Extension { // Run tests with different configs sequentially, group by config. const projectsToRunByModel = new Map(); - for (const project of selectedProjects) { + for (const project of projects) { const projects = projectsToRunByModel.get(project.model) || []; projects.push(project); projectsToRunByModel.set(project.model, projects); @@ -432,14 +444,14 @@ export class Extension { let ranSomeTests = false; try { for (const [model, projectsToRun] of projectsToRunByModel) { - const { projects, locations, parametrizedTestTitle } = this._narrowDownProjectsAndLocations(projectsToRun, request.include); + const { projects, locations, parametrizedTestTitle } = this._narrowDownProjectsAndLocations(projectsToRun, include); // Run if: // !locations => run all tests // locations.length => has matching items in project. if (locations && !locations.length) continue; ranSomeTests = true; - await this._runTest(this._testRun, testItemForGlobalErrors, new Set(), model, isDebug, projects, locations, parametrizedTestTitle, enqueuedTests.length === 1); + await this._runTest(this._testRun, testItemForGlobalErrors, new Set(), model, mode === 'debug', projects, locations, parametrizedTestTitle, enqueuedTests.length === 1); } } finally { this._activeSteps.clear(); @@ -455,8 +467,8 @@ located next to Run / Debug Tests toolbar buttons.`); } } - private _narrowDownProjectsAndLocations(projects: TestProject[], items: readonly vscodeTypes.TestItem[] | undefined): { projects: TestProject[], locations: string[] | null, parametrizedTestTitle: string | undefined } { - if (!items) + private _narrowDownProjectsAndLocations(projects: TestProject[], items: readonly vscodeTypes.TestItem[]): { projects: TestProject[], locations: string[] | null, parametrizedTestTitle: string | undefined } { + if (!items.length) return { projects, locations: null, parametrizedTestTitle: undefined }; let parametrizedTestTitle: string | undefined; @@ -507,7 +519,7 @@ located next to Run / Debug Tests toolbar buttons.`); await model.workspaceChanged(change); // Workspace change can be deferred, make sure editors are // decorated. - this._updateVisibleEditorItems(); + await this._updateVisibleEditorItems(); } private async _runTest( @@ -819,7 +831,7 @@ located next to Run / Debug Tests toolbar buttons.`); } browserServerWSForTest() { - return this._reusedBrowser.browserServerWSForTest(); + return this._reusedBrowser.browserServerWSEndpoint(); } private _showTrace(testItem: vscodeTypes.TestItem) { diff --git a/src/listTests.d.ts b/src/listTests.d.ts index 99032a0fd..5e5280e72 100644 --- a/src/listTests.d.ts +++ b/src/listTests.d.ts @@ -27,5 +27,11 @@ export type ProjectConfigWithFiles = { export type ConfigListFilesReport = { projects: ProjectConfigWithFiles[]; - error?: TestError + cliEntryPoint?: string; + error?: TestError; +}; + +export type ConfigFindRelatedTestFilesReport = { + testFiles: string[]; + errors?: TestError[]; }; diff --git a/src/playwrightTest.ts b/src/playwrightTest.ts index 0b0b01d7d..6e97a80fd 100644 --- a/src/playwrightTest.ts +++ b/src/playwrightTest.ts @@ -20,7 +20,6 @@ import { debugSessionName } from './debugSessionName'; import { ConfigListFilesReport } from './listTests'; import type { TestError, Entry, StepBeginParams, StepEndParams, TestBeginParams, TestEndParams } from './oopReporter'; import { ReporterServer } from './reporterServer'; -import { ReusedBrowser } from './reusedBrowser'; import { findNode, spawnAsync } from './utils'; import * as vscodeTypes from './vscodeTypes'; import { SettingsModel } from './settingsModel'; @@ -47,18 +46,29 @@ export interface TestListener { const pathSeparator = process.platform === 'win32' ? ';' : ':'; +export type PlaywrightTestOptions = { + projects?: string[]; + grep?: string; + connectWsEndpoint?: string; +}; + +export interface RunHooks { + onWillRunTests(config: TestConfig, debug: boolean): Promise<{ connectWsEndpoint?: string }>; + onDidRunTests(debug: boolean): Promise; +} + export class PlaywrightTest { private _testLog: string[] = []; private _isUnderTest: boolean; - private _reusedBrowser: ReusedBrowser; + private _runHooks: RunHooks; private _envProvider: () => NodeJS.ProcessEnv; private _vscode: vscodeTypes.VSCode; private _settingsModel: SettingsModel; - constructor(vscode: vscodeTypes.VSCode, settingsModel: SettingsModel, reusedBrowser: ReusedBrowser, isUnderTest: boolean, envProvider: () => NodeJS.ProcessEnv) { + constructor(vscode: vscodeTypes.VSCode, settingsModel: SettingsModel, runHooks: RunHooks, isUnderTest: boolean, envProvider: () => NodeJS.ProcessEnv) { this._vscode = vscode; this._settingsModel = settingsModel; - this._reusedBrowser = reusedBrowser; + this._runHooks = runHooks; this._isUnderTest = isUnderTest; this._envProvider = envProvider; } @@ -87,6 +97,10 @@ export class PlaywrightTest { try { const output = await this._runNode(allArgs, configFolder); const result = JSON.parse(output) as ConfigListFilesReport; + // TODO: merge getPlaywrightInfo and listFiles to avoid this. + // Override the cli entry point with the one obtained from the config. + if (result.cliEntryPoint) + config.cli = result.cliEntryPoint; return result; } catch (error: any) { return { @@ -101,36 +115,37 @@ export class PlaywrightTest { async runTests(config: TestConfig, projectNames: string[], locations: string[] | null, listener: TestListener, parametrizedTestTitle: string | undefined, token: vscodeTypes.CancellationToken) { const locationArg = locations ? locations : []; - const args = projectNames.filter(Boolean).map(p => `--project=${p}`); - if (parametrizedTestTitle) - args.push(`--grep=${escapeRegex(parametrizedTestTitle)}`); if (token?.isCancellationRequested) return; - await this._reusedBrowser.willRunTests(config, false); + const testOptions = await this._runHooks.onWillRunTests(config, false); try { if (token?.isCancellationRequested) return; - await this._test(config, locationArg, args, listener, 'run', token); + await this._test(config, locationArg, 'run', { + grep: parametrizedTestTitle, + projects: projectNames.filter(Boolean), + ...testOptions + }, listener, token); } finally { - await this._reusedBrowser.didRunTests(false); + await this._runHooks.onDidRunTests(false); } } async listTests(config: TestConfig, files: string[]): Promise<{ entries: Entry[], errors: TestError[] }> { let entries: Entry[] = []; const errors: TestError[] = []; - await this._test(config, files, ['--list'], { + await this._test(config, files, 'list', {}, { onBegin: params => { entries = params.projects as Entry[]; }, onError: params => { errors.push(params.error); }, - }, 'list', new this._vscode.CancellationTokenSource().token); + }, new this._vscode.CancellationTokenSource().token); return { entries, errors }; } - private async _test(config: TestConfig, locations: string[], args: string[], listener: TestListener, mode: 'list' | 'run', token: vscodeTypes.CancellationToken): Promise { + private async _test(config: TestConfig, locations: string[], mode: 'list' | 'run', options: PlaywrightTestOptions, listener: TestListener, token: vscodeTypes.CancellationToken): Promise { // Playwright will restart itself as child process in the ESM mode and won't inherit the 3/4 pipes. // Always use ws transport to mitigate it. const reporterServer = new ReporterServer(this._vscode); @@ -140,6 +155,15 @@ export class PlaywrightTest { const configFolder = path.dirname(config.configFile); const configFile = path.basename(config.configFile); const escapedLocations = locations.map(escapeRegex); + const args = []; + if (mode === 'list') + args.push('--list', '--reporter=null'); + + if (options.projects) + options.projects.forEach(p => args.push(`--project=${p}`)); + if (options.grep) + args.push(`--grep=${escapeRegex(options.grep)}`); + { // For tests. const relativeLocations = locations.map(f => path.relative(configFolder, f)).map(escapeRegex); @@ -152,16 +176,22 @@ export class PlaywrightTest { '--repeat-each', '1', '--retries', '0', ]; - const reusingBrowser = !!this._reusedBrowser.browserServerEnv(false); - if (reusingBrowser && !this._isUnderTest) - allArgs.push('--headed'); - if (reusingBrowser) - allArgs.push('--workers', '1'); - if (this._settingsModel.showTrace.get()) - allArgs.push('--trace', 'on'); - // Disable original reporters when listing files. - if (mode === 'list') - allArgs.push('--reporter', 'null'); + const showBrowser = this._settingsModel.showBrowser.get() && !!options.connectWsEndpoint; + if (mode === 'run') { + if (showBrowser && !this._isUnderTest) + allArgs.push('--headed'); + if (showBrowser) + allArgs.push('--workers', '1'); + if (this._settingsModel.showTrace.get()) + allArgs.push('--trace', 'on'); + // "Show browser" mode forces context reuse that survives over multiple test runs. + // Playwright Test sets up `tracesDir` inside the `test-results` folder, so it will be removed between runs. + // When context is reused, its ongoing tracing will fail with ENOENT because trace files + // were suddenly removed. So we disable tracing in this case. + if (this._settingsModel.showBrowser.get()) + allArgs.push('--trace', 'off'); + } + const childProcess = spawn(node, allArgs, { cwd: configFolder, stdio: ['pipe', 'pipe', 'pipe', 'pipe', 'pipe'], @@ -171,7 +201,8 @@ export class PlaywrightTest { // Don't debug tests when running them. NODE_OPTIONS: undefined, ...this._envProvider(), - ...this._reusedBrowser.browserServerEnv(false), + PW_TEST_REUSE_CONTEXT: showBrowser ? '1' : undefined, + PW_TEST_CONNECT_WS_ENDPOINT: showBrowser ? options.connectWsEndpoint : undefined, ...(await reporterServer.env()), // Reset VSCode's options that affect nested Electron. ELECTRON_RUN_AS_NODE: undefined, @@ -212,7 +243,7 @@ export class PlaywrightTest { } const reporterServer = new ReporterServer(this._vscode); - await this._reusedBrowser.willRunTests(config, true); + const testOptions = await this._runHooks.onWillRunTests(config, true); try { await vscode.debug.startDebugging(undefined, { type: 'pwa-node', @@ -223,7 +254,7 @@ export class PlaywrightTest { ...process.env, CI: this._isUnderTest ? undefined : process.env.CI, ...settingsEnv, - ...this._reusedBrowser.browserServerEnv(true), + PW_TEST_CONNECT_WS_ENDPOINT: testOptions.connectWsEndpoint, ...(await reporterServer.env()), // Reset VSCode's options that affect nested Electron. ELECTRON_RUN_AS_NODE: undefined, @@ -238,7 +269,7 @@ export class PlaywrightTest { }); await reporterServer.wireTestListener(listener, token); } finally { - await this._reusedBrowser.didRunTests(true); + await this._runHooks.onDidRunTests(true); } } diff --git a/src/reusedBrowser.ts b/src/reusedBrowser.ts index c75502662..d4cfeeff3 100644 --- a/src/reusedBrowser.ts +++ b/src/reusedBrowser.ts @@ -24,42 +24,8 @@ import { installBrowsers } from './installer'; import { SettingsModel } from './settingsModel'; import { BackendServer, BackendClient } from './backend'; -export type Snapshot = { - browsers: BrowserSnapshot[]; -}; - -export type BrowserSnapshot = { - contexts: ContextSnapshot[]; -}; - -export type ContextSnapshot = { - pages: PageSnapshot[]; -}; - -export type PageSnapshot = { - url: string; -}; - -export type SourceHighlight = { - line: number; - type: 'running' | 'paused' | 'error'; -}; - -export type Source = { - isRecorded: boolean; - id: string; - label: string; - text: string; - language: string; - highlight: SourceHighlight[]; - revealLine?: number; - // used to group the language generators - group?: string; -}; - export class ReusedBrowser implements vscodeTypes.Disposable { private _vscode: vscodeTypes.VSCode; - private _shouldReuseBrowserForTests = false; private _backend: Backend | undefined; private _cancelRecording: (() => void) | undefined; private _updateOrCancelInspecting: ((params: { selector?: string, cancel?: boolean }) => void) | undefined; @@ -77,6 +43,7 @@ export class ReusedBrowser implements vscodeTypes.Disposable { private _onRunningTestsChangedEvent: vscodeTypes.EventEmitter; private _editOperations = Promise.resolve(); private _pausedOnPagePause = false; + private _settingsModel: SettingsModel; constructor(vscode: vscodeTypes.VSCode, settingsModel: SettingsModel, envProvider: () => NodeJS.ProcessEnv) { this._vscode = vscode; @@ -87,13 +54,12 @@ export class ReusedBrowser implements vscodeTypes.Disposable { this.onRunningTestsChanged = this._onRunningTestsChangedEvent.event; this._onHighlightRequestedForTestEvent = new vscode.EventEmitter(); this.onHighlightRequestedForTest = this._onHighlightRequestedForTestEvent.event; + this._settingsModel = settingsModel; - this._disposables.push(settingsModel.reuseBrowser.onChange(value => { - this._shouldReuseBrowserForTests = value; + this._disposables.push(settingsModel.showBrowser.onChange(value => { if (!value) this.closeAllBrowsers(); })); - this._shouldReuseBrowserForTests = settingsModel.reuseBrowser.get(); } dispose() { @@ -220,19 +186,7 @@ export class ReusedBrowser implements vscodeTypes.Disposable { this._stop(); } - browserServerEnv(debug: boolean): NodeJS.ProcessEnv | undefined { - return (debug || this._shouldReuseBrowserForTests) && this._backend?.wsEndpoint ? { - PW_TEST_REUSE_CONTEXT: this._shouldReuseBrowserForTests ? '1' : undefined, - // "Show browser" mode forces context reuse that survives over multiple test runs. - // Playwright Test sets up `tracesDir` inside the `test-results` folder, so it will be removed between runs. - // When context is reused, its ongoing tracing will fail with ENOENT because trace files - // were suddenly removed. So we disable tracing in this case. - PW_TEST_DISABLE_TRACING: this._shouldReuseBrowserForTests ? '1' : undefined, - PW_TEST_CONNECT_WS_ENDPOINT: this._backend?.wsEndpoint, - } : undefined; - } - - browserServerWSForTest() { + browserServerWSEndpoint() { return this._backend?.wsEndpoint; } @@ -390,8 +344,8 @@ test('test', async ({ page }) => { return editor; } - async willRunTests(config: TestConfig, debug: boolean) { - if (!this._shouldReuseBrowserForTests && !debug) + async onWillRunTests(config: TestConfig, debug: boolean) { + if (!this._settingsModel.showBrowser.get() && !debug) return; if (!this._checkVersion(config, 'Show & reuse browser')) return; @@ -401,8 +355,8 @@ test('test', async ({ page }) => { await this._startBackendIfNeeded(config); } - async didRunTests(debug: boolean) { - if (debug && !this._shouldReuseBrowserForTests) { + async onDidRunTests(debug: boolean) { + if (debug && !this._settingsModel.showBrowser.get()) { this._stop(); } else { if (!this._pageCount) diff --git a/src/settingsModel.ts b/src/settingsModel.ts index 7583f4c5a..2fea10646 100644 --- a/src/settingsModel.ts +++ b/src/settingsModel.ts @@ -22,7 +22,7 @@ export class SettingsModel implements vscodeTypes.Disposable { readonly onChange: vscodeTypes.Event; private _onChange: vscodeTypes.EventEmitter; private _disposables: vscodeTypes.Disposable[] = []; - reuseBrowser: Setting; + showBrowser: Setting; showTrace: Setting; constructor(vscode: vscodeTypes.VSCode) { @@ -30,16 +30,16 @@ export class SettingsModel implements vscodeTypes.Disposable { this._onChange = new vscode.EventEmitter(); this.onChange = this._onChange.event; - this.reuseBrowser = this._createSetting('reuseBrowser'); + this.showBrowser = this._createSetting('reuseBrowser'); this.showTrace = this._createSetting('showTrace'); - this.reuseBrowser.onChange(enabled => { + this.showBrowser.onChange(enabled => { if (enabled && this.showTrace.get()) this.showTrace.set(false); }); this.showTrace.onChange(enabled => { - if (enabled && this.reuseBrowser.get()) - this.reuseBrowser.set(false); + if (enabled && this.showBrowser.get()) + this.showBrowser.set(false); }); } diff --git a/src/workspaceObserver.ts b/src/workspaceObserver.ts index 1f238465f..4742dc96b 100644 --- a/src/workspaceObserver.ts +++ b/src/workspaceObserver.ts @@ -62,7 +62,7 @@ export class WorkspaceObserver { } if (this._timeout) clearTimeout(this._timeout); - this._timeout = setTimeout(() => this._reportChange(), 500); + this._timeout = setTimeout(() => this._reportChange(), 50); return this._pendingChange; } diff --git a/tests/debug-tests.spec.ts b/tests/debug-tests.spec.ts index 7d6f552cb..5406d9a46 100644 --- a/tests/debug-tests.spec.ts +++ b/tests/debug-tests.spec.ts @@ -71,7 +71,7 @@ test('should debug one test', async ({ activate }) => { expect(vscode.renderExecLog(' ')).toBe(` > playwright list-files -c playwright.config.js - > playwright test -c playwright.config.js --list tests/test.spec.ts + > playwright test -c playwright.config.js --list --reporter=null tests/test.spec.ts > debug -c playwright.config.js tests/test.spec.ts:3 `); }); diff --git a/tests/decorations.spec.ts b/tests/decorations.spec.ts index 89121c68d..6fe08c574 100644 --- a/tests/decorations.spec.ts +++ b/tests/decorations.spec.ts @@ -65,7 +65,7 @@ test('should highlight steps while running', async ({ activate }) => { expect(vscode.renderExecLog(' ')).toBe(` > playwright list-files -c playwright.config.js - > playwright test -c playwright.config.js --list tests/test.spec.ts + > playwright test -c playwright.config.js --list --reporter=null tests/test.spec.ts > playwright test -c playwright.config.js `); }); diff --git a/tests/list-tests.spec.ts b/tests/list-tests.spec.ts index af2e3fc57..0f10b36cc 100644 --- a/tests/list-tests.spec.ts +++ b/tests/list-tests.spec.ts @@ -35,7 +35,7 @@ test('should list tests on expand', async ({ activate }) => { expect(vscode.renderExecLog(' ')).toBe(` > playwright list-files -c playwright.config.js - > playwright test -c playwright.config.js --list tests/test.spec.ts + > playwright test -c playwright.config.js --list --reporter=null tests/test.spec.ts `); }); @@ -65,7 +65,7 @@ test('should list tests for visible editors', async ({ activate }) => { expect(vscode.renderExecLog(' ')).toBe(` > playwright list-files -c playwright.config.js - > playwright test -c playwright.config.js --list tests/test1.spec.ts tests/test2.spec.ts + > playwright test -c playwright.config.js --list --reporter=null tests/test1.spec.ts tests/test2.spec.ts `); }); @@ -122,7 +122,7 @@ test('should discover new tests', async ({ activate }) => { expect(vscode.renderExecLog(' ')).toBe(` > playwright list-files -c playwright.config.js - > playwright test -c playwright.config.js --list tests/test.spec.ts + > playwright test -c playwright.config.js --list --reporter=null tests/test.spec.ts `); await Promise.all([ @@ -143,8 +143,8 @@ test('should discover new tests', async ({ activate }) => { expect(vscode.renderExecLog(' ')).toBe(` > playwright list-files -c playwright.config.js - > playwright test -c playwright.config.js --list tests/test.spec.ts - > playwright test -c playwright.config.js --list tests/test.spec.ts + > playwright test -c playwright.config.js --list --reporter=null tests/test.spec.ts + > playwright test -c playwright.config.js --list --reporter=null tests/test.spec.ts `); }); @@ -186,7 +186,7 @@ test('should discover new tests with active editor', async ({ activate }) => { expect(vscode.renderExecLog(' ')).toBe(` > playwright list-files -c playwright.config.js > playwright list-files -c playwright.config.js - > playwright test -c playwright.config.js --list tests/test2.spec.ts + > playwright test -c playwright.config.js --list --reporter=null tests/test2.spec.ts `); }); @@ -222,8 +222,8 @@ test('should discover tests on add + change', async ({ activate }) => { expect(vscode.renderExecLog(' ')).toBe(` > playwright list-files -c playwright.config.js > playwright list-files -c playwright.config.js - > playwright test -c playwright.config.js --list test.spec.ts - > playwright test -c playwright.config.js --list test.spec.ts + > playwright test -c playwright.config.js --list --reporter=null test.spec.ts + > playwright test -c playwright.config.js --list --reporter=null test.spec.ts `); }); @@ -240,7 +240,7 @@ test('should discover new test at existing location', async ({ activate }) => { expect(vscode.renderExecLog(' ')).toBe(` > playwright list-files -c playwright.config.js - > playwright test -c playwright.config.js --list tests/test.spec.ts + > playwright test -c playwright.config.js --list --reporter=null tests/test.spec.ts `); await Promise.all([ @@ -259,8 +259,8 @@ test('should discover new test at existing location', async ({ activate }) => { expect(vscode.renderExecLog(' ')).toBe(` > playwright list-files -c playwright.config.js - > playwright test -c playwright.config.js --list tests/test.spec.ts - > playwright test -c playwright.config.js --list tests/test.spec.ts + > playwright test -c playwright.config.js --list --reporter=null tests/test.spec.ts + > playwright test -c playwright.config.js --list --reporter=null tests/test.spec.ts `); }); @@ -278,7 +278,7 @@ test('should remove deleted tests', async ({ activate }) => { expect(vscode.renderExecLog(' ')).toBe(` > playwright list-files -c playwright.config.js - > playwright test -c playwright.config.js --list tests/test.spec.ts + > playwright test -c playwright.config.js --list --reporter=null tests/test.spec.ts `); expect(testController.renderTestTree()).toBe(` @@ -304,8 +304,8 @@ test('should remove deleted tests', async ({ activate }) => { expect(vscode.renderExecLog(' ')).toBe(` > playwright list-files -c playwright.config.js - > playwright test -c playwright.config.js --list tests/test.spec.ts - > playwright test -c playwright.config.js --list tests/test.spec.ts + > playwright test -c playwright.config.js --list --reporter=null tests/test.spec.ts + > playwright test -c playwright.config.js --list --reporter=null tests/test.spec.ts `); }); @@ -359,7 +359,7 @@ test('should regain tests after error is fixed', async ({ activate }) => { expect(vscode.renderExecLog(' ')).toBe(` > playwright list-files -c playwright.config.js - > playwright test -c playwright.config.js --list tests/test.spec.ts + > playwright test -c playwright.config.js --list --reporter=null tests/test.spec.ts `); expect(testController.renderTestTree()).toBe(` @@ -385,8 +385,8 @@ test('should regain tests after error is fixed', async ({ activate }) => { expect(vscode.renderExecLog(' ')).toBe(` > playwright list-files -c playwright.config.js - > playwright test -c playwright.config.js --list tests/test.spec.ts - > playwright test -c playwright.config.js --list tests/test.spec.ts + > playwright test -c playwright.config.js --list --reporter=null tests/test.spec.ts + > playwright test -c playwright.config.js --list --reporter=null tests/test.spec.ts `); }); @@ -418,8 +418,8 @@ test('should support multiple configs', async ({ activate }) => { expect(vscode.renderExecLog(' ')).toBe(` tests1> playwright list-files -c playwright.config.js tests2> playwright list-files -c playwright.config.js - tests1> playwright test -c playwright.config.js --list test.spec.ts - tests2> playwright test -c playwright.config.js --list test.spec.ts + tests1> playwright test -c playwright.config.js --list --reporter=null test.spec.ts + tests2> playwright test -c playwright.config.js --list --reporter=null test.spec.ts `); }); @@ -453,7 +453,7 @@ test('should support multiple projects', async ({ activate }) => { expect(vscode.renderExecLog(' ')).toBe(` > playwright list-files -c playwright.config.js - > playwright test -c playwright.config.js --list tests/test1.spec.ts + > playwright test -c playwright.config.js --list --reporter=null tests/test1.spec.ts `); }); diff --git a/tests/run-tests.spec.ts b/tests/run-tests.spec.ts index 9f79175e5..5ce472bdb 100644 --- a/tests/run-tests.spec.ts +++ b/tests/run-tests.spec.ts @@ -72,7 +72,7 @@ test('should run one test', async ({ activate }) => { expect(vscode.renderExecLog(' ')).toBe(` > playwright list-files -c playwright.config.js - > playwright test -c playwright.config.js --list tests/test.spec.ts + > playwright test -c playwright.config.js --list --reporter=null tests/test.spec.ts > playwright test -c playwright.config.js tests/test.spec.ts:3 `); }); @@ -339,7 +339,6 @@ test('should only create test run if folder belongs to context', async ({ activa const items = testController.findTestItems(/foo1/); await Promise.all(profiles.map(p => p.run(items))); expect(testRuns).toHaveLength(1); - expect(testRuns[0].request.profile).toBe(profiles[0]); expect(vscode.renderExecLog(' ')).toBe(` tests1> playwright list-files -c playwright.config.js @@ -373,7 +372,7 @@ test('should only create test run if test belongs to context', async ({ activate expect(vscode.renderExecLog(' ')).toBe(` tests1> playwright list-files -c playwright.config.js tests2> playwright list-files -c playwright.config.js - tests2> playwright test -c playwright.config.js --list foo2/bar2/test2.spec.ts + tests2> playwright test -c playwright.config.js --list --reporter=null foo2/bar2/test2.spec.ts tests2> playwright test -c playwright.config.js foo2/bar2/test2.spec.ts:3 `); }); @@ -561,7 +560,7 @@ test('should run all parametrized tests', async ({ activate }) => { expect(vscode.renderExecLog(' ')).toBe(` > playwright list-files -c playwright.config.js - > playwright test -c playwright.config.js --list tests/test.spec.ts + > playwright test -c playwright.config.js --list --reporter=null tests/test.spec.ts > playwright test -c playwright.config.js tests/test.spec.ts:4 `); }); @@ -591,7 +590,7 @@ test('should run one parametrized test', async ({ activate }) => { expect(vscode.renderExecLog(' ')).toBe(` > playwright list-files -c playwright.config.js - > playwright test -c playwright.config.js --list tests/test.spec.ts + > playwright test -c playwright.config.js --list --reporter=null tests/test.spec.ts > playwright test -c playwright.config.js --grep=test two tests/test.spec.ts:4 `); }); @@ -629,7 +628,7 @@ test('should run one parametrized groups', async ({ activate }) => { expect(vscode.renderExecLog(' ')).toBe(` > playwright list-files -c playwright.config.js - > playwright test -c playwright.config.js --list tests/test.spec.ts + > playwright test -c playwright.config.js --list --reporter=null tests/test.spec.ts > playwright test -c playwright.config.js --grep=group three tests/test.spec.ts:4 `); }); @@ -663,7 +662,7 @@ test('should run tests in parametrized groups', async ({ activate }) => { expect(vscode.renderExecLog(' ')).toBe(` > playwright list-files -c playwright.config.js - > playwright test -c playwright.config.js --list tests/test.spec.ts + > playwright test -c playwright.config.js --list --reporter=null tests/test.spec.ts > playwright test -c playwright.config.js --grep=level 1 tests/test.spec.ts:4 `); @@ -680,7 +679,7 @@ test('should run tests in parametrized groups', async ({ activate }) => { expect(vscode.renderExecLog(' ')).toBe(` > playwright list-files -c playwright.config.js - > playwright test -c playwright.config.js --list tests/test.spec.ts + > playwright test -c playwright.config.js --list --reporter=null tests/test.spec.ts > playwright test -c playwright.config.js --grep=level 1 tests/test.spec.ts:4 > playwright test -c playwright.config.js --grep=level 2 tests/test.spec.ts:4 `); @@ -699,7 +698,7 @@ test('should list tests in relative folder', async ({ activate }) => { expect(vscode.renderExecLog(' ')).toBe(` foo/bar> playwright list-files -c playwright.config.js - foo/bar> playwright test -c playwright.config.js --list ../../tests/test.spec.ts + foo/bar> playwright test -c playwright.config.js --list --reporter=null ../../tests/test.spec.ts `); expect(testController.renderTestTree()).toBe(` diff --git a/tests/source-map.spec.ts b/tests/source-map.spec.ts index 9c6f1f34b..afda7ae7e 100644 --- a/tests/source-map.spec.ts +++ b/tests/source-map.spec.ts @@ -50,7 +50,7 @@ test('should list tests on expand', async ({ activate }) => { expect(vscode.renderExecLog(' ')).toBe(` > playwright list-files -c playwright.config.js - > playwright test -c playwright.config.js --list tests/test.spec.ts + > playwright test -c playwright.config.js --list --reporter=null tests/test.spec.ts `); }); @@ -74,7 +74,7 @@ test('should list tests for visible editors', async ({ activate }) => { expect(vscode.renderExecLog(' ')).toBe(` > playwright list-files -c playwright.config.js - > playwright test -c playwright.config.js --list tests/test.spec.ts + > playwright test -c playwright.config.js --list --reporter=null tests/test.spec.ts `); }); @@ -169,7 +169,7 @@ test('should discover new tests', async ({ activate }) => { expect(vscode.renderExecLog(' ')).toBe(` > playwright list-files -c playwright.config.js - > playwright test -c playwright.config.js --list tests/test.spec.ts + > playwright test -c playwright.config.js --list --reporter=null tests/test.spec.ts `); await Promise.all([ @@ -189,8 +189,8 @@ test('should discover new tests', async ({ activate }) => { expect(vscode.renderExecLog(' ')).toBe(` > playwright list-files -c playwright.config.js - > playwright test -c playwright.config.js --list tests/test.spec.ts - > playwright test -c playwright.config.js --list tests/test.spec.ts + > playwright test -c playwright.config.js --list --reporter=null tests/test.spec.ts + > playwright test -c playwright.config.js --list --reporter=null tests/test.spec.ts `); }); @@ -242,7 +242,7 @@ test('should run one test', async ({ activate }) => { expect(vscode.renderExecLog(' ')).toBe(` > playwright list-files -c playwright.config.js - > playwright test -c playwright.config.js --list tests/test.spec.ts + > playwright test -c playwright.config.js --list --reporter=null tests/test.spec.ts > playwright test -c playwright.config.js tests/test.spec.ts:3 `); });