diff --git a/src/extension.ts b/src/extension.ts index b887cf333..720fb1b61 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -392,15 +392,19 @@ export class Extension implements RunHooks { } } + const items: vscodeTypes.TestItem[] = include ? [...include] : []; try { for (const model of this._models.enabledModels()) { + const result = model.narrowDownLocations(items); + if (!result.testIds && !result.locations) + continue; let globalSetupResult: reporterTypes.FullResult['status'] = 'passed'; if (model.canRunGlobalHooks('setup')) { - const testListener = this._errorReportingListener(this._testRun); + const testListener = this._errorReportingListener(this._testRun, testItemForGlobalErrors); globalSetupResult = await model.runGlobalHooks('setup', testListener); } if (globalSetupResult === 'passed') - await this._runTest(this._testRun, include ? [...include] : [], testItemForGlobalErrors, new Set(), model, mode === 'debug', enqueuedTests.length === 1); + await this._runTest(this._testRun, items, testItemForGlobalErrors, new Set(), model, mode === 'debug', enqueuedTests.length === 1); } } finally { this._activeSteps.clear(); diff --git a/src/playwrightTestServer.ts b/src/playwrightTestServer.ts index 4a2d0c04d..5e776a586 100644 --- a/src/playwrightTestServer.ts +++ b/src/playwrightTestServer.ts @@ -26,8 +26,6 @@ import { escapeRegex, pathSeparator } from './utils'; import { debugSessionName } from './debugSessionName'; import type { TestModel } from './testModel'; import { TestServerInterface } from './upstream/testServerInterface'; -import { upstreamTreeItem } from './testTree'; -import { collectTestIds } from './upstream/testTree'; export class PlaywrightTestServer { private _vscode: vscodeTypes.VSCode; @@ -142,7 +140,7 @@ export class PlaywrightTestServer { if (!testServer) return; - const { locations, testIds } = this._narrowDownLocations(items); + const { locations, testIds } = this._model.narrowDownLocations(items); if (!locations && !testIds) return; @@ -220,7 +218,7 @@ export class PlaywrightTestServer { if (token?.isCancellationRequested) return; - const { locations, testIds } = this._narrowDownLocations(items); + const { locations, testIds } = this._model.narrowDownLocations(items); if (!locations && !testIds) return; @@ -247,7 +245,7 @@ export class PlaywrightTestServer { await testEndPromise; } finally { disposable?.dispose(); - testServer?.closeGracefully({}); + testServer?.close(); await this._options.runHooks.onDidRunTests(true); } } @@ -319,27 +317,7 @@ export class PlaywrightTestServer { const testServer = this._testServerPromise; this._testServerPromise = undefined; if (testServer) - testServer.then(server => server?.closeGracefully({})); - } - - private _narrowDownLocations(items: vscodeTypes.TestItem[]): { locations: string[] | null, testIds?: string[] } { - if (!items.length) - return { locations: [] }; - const locations = new Set(); - const testIds: string[] = []; - for (const item of items) { - const treeItem = upstreamTreeItem(item); - if (treeItem.kind === 'group' && (treeItem.subKind === 'folder' || treeItem.subKind === 'file')) { - for (const file of this._model.enabledFiles()) { - if (file === treeItem.location.file || file.startsWith(treeItem.location.file)) - locations.add(treeItem.location.file); - } - } else { - testIds.push(...collectTestIds(treeItem)); - } - } - - return { locations: locations.size ? [...locations] : null, testIds: testIds.length ? testIds : undefined }; + testServer.then(server => server?.close()); } } diff --git a/src/testModel.ts b/src/testModel.ts index 5f58aa3fe..be8540518 100644 --- a/src/testModel.ts +++ b/src/testModel.ts @@ -27,6 +27,8 @@ import { MultiMap } from './multimap'; import { PlaywrightTestServer } from './playwrightTestServer'; import type { PlaywrightTestRunOptions, RunHooks, TestConfig } from './playwrightTestTypes'; import { PlaywrightTestCLI } from './playwrightTestCLI'; +import { upstreamTreeItem } from './testTree'; +import { collectTestIds } from './upstream/testTree'; export type TestEntry = reporterTypes.TestCase | reporterTypes.Suite; @@ -508,6 +510,26 @@ export class TestModel { } } } + + narrowDownLocations(items: vscodeTypes.TestItem[]): { locations: string[] | null, testIds?: string[] } { + if (!items.length) + return { locations: [] }; + const locations = new Set(); + const testIds: string[] = []; + for (const item of items) { + const treeItem = upstreamTreeItem(item); + if (treeItem.kind === 'group' && (treeItem.subKind === 'folder' || treeItem.subKind === 'file')) { + for (const file of this.enabledFiles()) { + if (file === treeItem.location.file || file.startsWith(treeItem.location.file)) + locations.add(treeItem.location.file); + } + } else { + testIds.push(...collectTestIds(treeItem)); + } + } + + return { locations: locations.size ? [...locations] : null, testIds: testIds.length ? testIds : undefined }; + } } export class TestModelCollection extends DisposableBase { diff --git a/src/upstream/testServerConnection.ts b/src/upstream/testServerConnection.ts index b4814e182..5ff5523cd 100644 --- a/src/upstream/testServerConnection.ts +++ b/src/upstream/testServerConnection.ts @@ -184,4 +184,11 @@ export class TestServerConnection implements TestServerInterface, TestServerInte async closeGracefully(params: Parameters[0]): ReturnType { await this._sendMessage('closeGracefully', params); } + + close() { + try { + this._ws.close(); + } catch { + } + } } diff --git a/tests/debug-tests.spec.ts b/tests/debug-tests.spec.ts index 7ecb9465c..d4aa02783 100644 --- a/tests/debug-tests.spec.ts +++ b/tests/debug-tests.spec.ts @@ -16,6 +16,7 @@ import { expect, test } from './utils'; import { TestRun } from './mock/vscode'; +import path from 'path'; test('should debug all tests', async ({ activate }) => { const { vscode } = await activate({ @@ -46,6 +47,17 @@ test('should debug all tests', async ({ activate }) => { > playwright list-files -c playwright.config.js > debug -c playwright.config.js `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { method: 'runGlobalSetup', params: {} }, + { + method: 'runTests', + params: expect.objectContaining({ + locations: [], + testIds: undefined + }) + }, + ]); }); test('should debug one test', async ({ activate }) => { @@ -74,6 +86,23 @@ test('should debug one test', async ({ activate }) => { > playwright test -c playwright.config.js --list --reporter=null tests/test.spec.ts > debug -c playwright.config.js tests/test.spec.ts:3 `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { + method: 'listTests', + params: expect.objectContaining({ + locations: [expect.stringContaining(`tests${path.sep}test\\.spec\\.ts`)] + }) + }, + { method: 'runGlobalSetup', params: {} }, + { + method: 'runTests', + params: expect.objectContaining({ + locations: undefined, + testIds: [expect.any(String)] + }) + }, + ]); }); test('should debug error', async ({ activate }, testInfo) => { diff --git a/tests/decorations.spec.ts b/tests/decorations.spec.ts index fdc419335..c463bd24d 100644 --- a/tests/decorations.spec.ts +++ b/tests/decorations.spec.ts @@ -15,6 +15,7 @@ */ import { expect, test } from './utils'; +import path from 'path'; test('should highlight steps while running', async ({ activate }) => { const { vscode, testController } = await activate({ @@ -68,4 +69,21 @@ test('should highlight steps while running', async ({ activate }) => { > playwright test -c playwright.config.js --list --reporter=null tests/test.spec.ts > playwright test -c playwright.config.js `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { + method: 'listTests', + params: expect.objectContaining({ + locations: [expect.stringContaining(`tests${path.sep}test\\.spec\\.ts`)] + }) + }, + { method: 'runGlobalSetup', params: {} }, + { + method: 'runTests', + params: expect.objectContaining({ + locations: [], + testIds: undefined + }) + }, + ]); }); diff --git a/tests/global-errors.spec.ts b/tests/global-errors.spec.ts index 4291bbcf4..498d10ff5 100644 --- a/tests/global-errors.spec.ts +++ b/tests/global-errors.spec.ts @@ -73,6 +73,17 @@ test('should report error in global setup (implicit)', async ({ activate, useTes > playwright list-files -c playwright.config.js > playwright test -c playwright.config.js `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { method: 'runGlobalSetup', params: {} }, + { + method: 'runTests', + params: expect.objectContaining({ + locations: [], + testIds: undefined + }) + }, + ]); }); test('should report error in global setup (explicit)', async ({ activate, useTestServer }) => { @@ -101,4 +112,8 @@ test('should report error in global setup (explicit)', async ({ activate, useTes > playwright list-files -c playwright.config.js > playwright test -c playwright.config.js `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { method: 'runGlobalSetup', params: {} }, + ]); }); diff --git a/tests/list-files.spec.ts b/tests/list-files.spec.ts index 85590fc39..d52d128d1 100644 --- a/tests/list-files.spec.ts +++ b/tests/list-files.spec.ts @@ -32,6 +32,9 @@ test('should list files', async ({ activate }) => { await expect(vscode).toHaveExecLog(` > playwright list-files -c playwright.config.js `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} } + ]); }); test('should list files top level if no testDir', async ({ activate }, testInfo) => { @@ -49,6 +52,9 @@ test('should list files top level if no testDir', async ({ activate }, testInfo) await expect(vscode).toHaveExecLog(` > playwright list-files -c playwright.config.js `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} } + ]); }); test('should list only test files', async ({ activate }) => { @@ -94,6 +100,9 @@ test('should list folders', async ({ activate }) => { await expect(vscode).toHaveExecLog(` > playwright list-files -c playwright.config.js `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} } + ]); }); test('should pick new files', async ({ activate }) => { @@ -110,6 +119,9 @@ test('should pick new files', async ({ activate }) => { await expect(vscode).toHaveExecLog(` > playwright list-files -c playwright.config.js `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} } + ]); await Promise.all([ new Promise(f => testController.onDidChangeTestItem(f)), @@ -126,6 +138,10 @@ test('should pick new files', async ({ activate }) => { > playwright list-files -c playwright.config.js > playwright list-files -c playwright.config.js `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { method: 'listFiles', params: {} } + ]); }); test('should not pick non-test files', async ({ activate }) => { @@ -189,6 +205,9 @@ test('should remove deleted files', async ({ activate }) => { await expect(vscode).toHaveExecLog(` > playwright list-files -c playwright.config.js `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} } + ]); await Promise.all([ new Promise(f => testController.onDidChangeTestItem(f)), @@ -205,6 +224,10 @@ test('should remove deleted files', async ({ activate }) => { > playwright list-files -c playwright.config.js > playwright list-files -c playwright.config.js `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { method: 'listFiles', params: {} } + ]); }); test('should do nothing for not loaded changed file', async ({ activate }) => { @@ -256,6 +279,9 @@ test('should support multiple projects', async ({ activate }) => { await expect(vscode).toHaveExecLog(` > playwright list-files -c playwright.config.js `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} } + ]); }); test('should switch between multiple projects with filter', async ({ activate }) => { @@ -288,6 +314,9 @@ test('should switch between multiple projects with filter', async ({ activate }) await expect(vscode).toHaveExecLog(` > playwright list-files -c playwright.config.js `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} } + ]); await expect(vscode).toHaveProjectTree(` config: playwright.config.js @@ -311,6 +340,9 @@ test('should switch between multiple projects with filter', async ({ activate }) await expect(vscode).toHaveExecLog(` > playwright list-files -c playwright.config.js `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} } + ]); }); test('should list files in relative folder', async ({ activate }) => { @@ -328,6 +360,9 @@ test('should list files in relative folder', async ({ activate }) => { await expect(vscode).toHaveExecLog(` foo/bar> playwright list-files -c playwright.config.js `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} } + ]); }); test('should list files in multi-folder workspace with project switching', async ({ activate }, testInfo) => { @@ -386,6 +421,10 @@ test('should ignore errors when listing files', async ({ activate }) => { > playwright list-files -c playwright.config.js > playwright list-files -c playwright.config.ts `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { method: 'listFiles', params: {} } + ]); await new Promise(f => setTimeout(f, 2000)); await expect.poll(() => vscode.languages.getDiagnostics()).toEqual([ diff --git a/tests/list-tests.spec.ts b/tests/list-tests.spec.ts index 0c34ca39e..4ac9ae4b9 100644 --- a/tests/list-tests.spec.ts +++ b/tests/list-tests.spec.ts @@ -38,6 +38,15 @@ test('should list tests on expand', async ({ activate }) => { > playwright list-files -c playwright.config.js > playwright test -c playwright.config.js --list --reporter=null tests/test.spec.ts `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { + method: 'listTests', + params: { + locations: [expect.stringContaining(`tests${path.sep}test\\.spec\\.ts`)] + } + }, + ]); }); test('should list tests for visible editors', async ({ activate }) => { @@ -68,6 +77,18 @@ test('should list tests for visible editors', async ({ activate }) => { > playwright list-files -c playwright.config.js > playwright test -c playwright.config.js --list --reporter=null tests/test1.spec.ts tests/test2.spec.ts `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { + method: 'listTests', + params: { + locations: [ + expect.stringContaining(`tests${path.sep}test1\\.spec\\.ts`), + expect.stringContaining(`tests${path.sep}test2\\.spec\\.ts`), + ] + } + }, + ]); }); test('should list suits', async ({ activate }) => { @@ -125,6 +146,15 @@ test('should discover new tests', async ({ activate }) => { > playwright list-files -c playwright.config.js > playwright test -c playwright.config.js --list --reporter=null tests/test.spec.ts `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { + method: 'listTests', + params: { + locations: [expect.stringContaining(`tests${path.sep}test\\.spec\\.ts`)] + } + }, + ]); await Promise.all([ new Promise(f => testController.onDidChangeTestItem(f)), @@ -147,6 +177,21 @@ test('should discover new tests', async ({ activate }) => { > 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 `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { + method: 'listTests', + params: { + locations: [expect.stringContaining(`tests${path.sep}test\\.spec\\.ts`)] + } + }, + { + method: 'listTests', + params: { + locations: [expect.stringContaining(`tests${path.sep}test\\.spec\\.ts`)] + } + }, + ]); }); test('should discover new tests with active editor', async ({ activate }) => { @@ -161,7 +206,9 @@ test('should discover new tests with active editor', async ({ activate }) => { await expect(vscode).toHaveExecLog(` > playwright list-files -c playwright.config.js `); - + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + ]); await workspaceFolder.addFile('tests/test2.spec.ts', ` import { test } from '@playwright/test'; test('two', async () => {}); @@ -171,7 +218,10 @@ test('should discover new tests with active editor', async ({ activate }) => { > playwright list-files -c playwright.config.js > playwright list-files -c playwright.config.js `); - + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { method: 'listFiles', params: {} }, + ]); await Promise.all([ new Promise(f => { testController.onDidChangeTestItem(ti => { @@ -194,6 +244,16 @@ test('should discover new tests with active editor', async ({ activate }) => { > playwright list-files -c playwright.config.js > playwright test -c playwright.config.js --list --reporter=null tests/test2.spec.ts `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { method: 'listFiles', params: {} }, + { + method: 'listTests', + params: { + locations: [expect.stringContaining(`tests${path.sep}test2\\.spec\\.ts`)] + } + }, + ]); }); test('should discover tests on add + change', async ({ activate }) => { @@ -231,6 +291,22 @@ test('should discover tests on add + change', async ({ activate }) => { > playwright test -c playwright.config.js --list --reporter=null test.spec.ts > playwright test -c playwright.config.js --list --reporter=null test.spec.ts `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { method: 'listFiles', params: {} }, + { + method: 'listTests', + params: { + locations: [expect.stringContaining(`test\\.spec\\.ts`)] + } + }, + { + method: 'listTests', + params: { + locations: [expect.stringContaining(`test\\.spec\\.ts`)] + } + }, + ]); }); test('should discover new test at existing location', async ({ activate }) => { @@ -248,6 +324,15 @@ test('should discover new test at existing location', async ({ activate }) => { > playwright list-files -c playwright.config.js > playwright test -c playwright.config.js --list --reporter=null tests/test.spec.ts `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { + method: 'listTests', + params: { + locations: [expect.stringContaining(`tests${path.sep}test\\.spec\\.ts`)] + } + }, + ]); await Promise.all([ new Promise(f => testController.onDidChangeTestItem(f)), @@ -268,6 +353,21 @@ test('should discover new test at existing location', async ({ activate }) => { > 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 `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { + method: 'listTests', + params: { + locations: [expect.stringContaining(`tests${path.sep}test\\.spec\\.ts`)] + } + }, + { + method: 'listTests', + params: { + locations: [expect.stringContaining(`tests${path.sep}test\\.spec\\.ts`)] + } + }, + ]); }); test('should remove deleted tests', async ({ activate }) => { @@ -286,6 +386,15 @@ test('should remove deleted tests', async ({ activate }) => { > playwright list-files -c playwright.config.js > playwright test -c playwright.config.js --list --reporter=null tests/test.spec.ts `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { + method: 'listTests', + params: { + locations: [expect.stringContaining(`tests${path.sep}test\\.spec\\.ts`)] + } + }, + ]); await expect(testController).toHaveTestTree(` - tests @@ -313,6 +422,21 @@ test('should remove deleted tests', async ({ activate }) => { > 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 `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { + method: 'listTests', + params: { + locations: [expect.stringContaining(`tests${path.sep}test\\.spec\\.ts`)] + } + }, + { + method: 'listTests', + params: { + locations: [expect.stringContaining(`tests${path.sep}test\\.spec\\.ts`)] + } + }, + ]); }); test('should forget tests after error before first test', async ({ activate }) => { @@ -367,6 +491,15 @@ test('should regain tests after error is fixed', async ({ activate }) => { > playwright list-files -c playwright.config.js > playwright test -c playwright.config.js --list --reporter=null tests/test.spec.ts `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { + method: 'listTests', + params: { + locations: [expect.stringContaining(`tests${path.sep}test\\.spec\\.ts`)] + } + }, + ]); await expect(testController).toHaveTestTree(` - tests @@ -394,6 +527,21 @@ test('should regain tests after error is fixed', async ({ activate }) => { > 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 `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { + method: 'listTests', + params: { + locations: [expect.stringContaining(`tests${path.sep}test\\.spec\\.ts`)] + } + }, + { + method: 'listTests', + params: { + locations: [expect.stringContaining(`tests${path.sep}test\\.spec\\.ts`)] + } + }, + ]); }); test('should support multiple configs', async ({ activate }) => { @@ -436,6 +584,22 @@ test('should support multiple configs', async ({ activate }) => { 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 `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { method: 'listFiles', params: {} }, + { + method: 'listTests', + params: { + locations: [expect.stringContaining(`tests1${path.sep}test\\.spec\\.ts`)] + } + }, + { + method: 'listTests', + params: { + locations: [expect.stringContaining(`tests2${path.sep}test\\.spec\\.ts`)] + } + }, + ]); }); test('should support multiple projects', async ({ activate }) => { @@ -478,6 +642,15 @@ test('should support multiple projects', async ({ activate }) => { > playwright list-files -c playwright.config.js > playwright test -c playwright.config.js --list --reporter=null tests/test1.spec.ts `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { + method: 'listTests', + params: { + locations: [expect.stringContaining(`tests${path.sep}test1\\.spec\\.ts`)] + } + }, + ]); }); test('should list parametrized tests', async ({ activate }) => { diff --git a/tests/mock/vscode.ts b/tests/mock/vscode.ts index 040256610..3a11a10ed 100644 --- a/tests/mock/vscode.ts +++ b/tests/mock/vscode.ts @@ -449,11 +449,9 @@ export class TestRun { } private _renderOutput(): string[] { - const result: string[] = []; const output = this.output.map(o => o.output).join(''); const lines = output.split('\n'); - result.push(...lines.map(l => ' ' + stripAnsi(l).replace(/\d+(\.\d+)?(ms|s)/, 'XXms'))); - return result; + return lines.map(l => ' ' + stripAnsi(l).replace(/\d+(\.\d+)?(ms|s)/, 'XXms')); } } @@ -846,12 +844,13 @@ export class VSCode { lastWithProgressData = undefined; private _hoverProviders: Map = new Map(); readonly version: string; + readonly connectionLog: any[] = []; constructor(readonly versionNumber: number, baseDir: string, browser: Browser) { this.version = String(versionNumber); this.context = { subscriptions: [], extensionUri: Uri.file(baseDir) }; this._browser = browser; - + (globalThis as any).__logForTest = message => this.connectionLog.push(message); const commands = new Map Promise>(); this.commands.registerCommand = (name: string, callback: () => Promise) => { commands.set(name, callback); diff --git a/tests/project-tree.spec.ts b/tests/project-tree.spec.ts index 6a448ee11..35d5e5e43 100644 --- a/tests/project-tree.spec.ts +++ b/tests/project-tree.spec.ts @@ -43,6 +43,9 @@ test('should switch between configs', async ({ activate }) => { await expect(vscode).toHaveExecLog(` tests1> playwright list-files -c playwright.config.js `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + ]); await enableConfigs(vscode, [`tests2${path.sep}playwright.config.js`]); @@ -60,6 +63,10 @@ test('should switch between configs', async ({ activate }) => { tests1> playwright list-files -c playwright.config.js tests2> playwright list-files -c playwright.config.js `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { method: 'listFiles', params: {} }, + ]); }); test('should switch between projects', async ({ activate }) => { diff --git a/tests/run-annotations.spec.ts b/tests/run-annotations.spec.ts index 73c8657ad..b991d7b27 100644 --- a/tests/run-annotations.spec.ts +++ b/tests/run-annotations.spec.ts @@ -59,4 +59,15 @@ test('should mark test as skipped', async ({ activate }) => { > playwright list-files -c playwright.config.js > playwright test -c playwright.config.js `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { method: 'runGlobalSetup', params: {} }, + { + method: 'runTests', + params: expect.objectContaining({ + locations: [], + testIds: undefined + }) + }, + ]); }); diff --git a/tests/run-tests.spec.ts b/tests/run-tests.spec.ts index 63e82e95d..60597712c 100644 --- a/tests/run-tests.spec.ts +++ b/tests/run-tests.spec.ts @@ -57,6 +57,14 @@ test('should run all tests', async ({ activate }) => { > playwright list-files -c playwright.config.js > playwright test -c playwright.config.js `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { method: 'runGlobalSetup', params: {} }, + { method: 'runTests', params: expect.objectContaining({ + locations: [], + testIds: undefined, + }) }, + ]); }); test('should run one test', async ({ activate }) => { @@ -91,6 +99,23 @@ test('should run one test', async ({ activate }) => { > playwright test -c playwright.config.js --list --reporter=null tests/test.spec.ts > playwright test -c playwright.config.js tests/test.spec.ts:3 `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { + method: 'listTests', + params: { + locations: [expect.stringContaining(`tests${path.sep}test\\.spec\\.ts`)] + } + }, + { method: 'runGlobalSetup', params: {} }, + { + method: 'runTests', + params: expect.objectContaining({ + locations: undefined, + testIds: [expect.any(String)] + }) + }, + ]); }); test('should run describe', async ({ activate }) => { @@ -153,6 +178,17 @@ test('should run file', async ({ activate }) => { > playwright list-files -c playwright.config.js > playwright test -c playwright.config.js tests/test.spec.ts `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { method: 'runGlobalSetup', params: {} }, + { + method: 'runTests', + params: expect.objectContaining({ + locations: [expect.stringContaining(`tests${path.sep}test\\.spec\\.ts`)], + testIds: undefined + }) + }, + ]); }); test('should run folder', async ({ activate }) => { @@ -187,6 +223,17 @@ test('should run folder', async ({ activate }) => { > playwright list-files -c playwright.config.js > playwright test -c playwright.config.js tests/folder `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { method: 'runGlobalSetup', params: {} }, + { + method: 'runTests', + params: expect.objectContaining({ + locations: [expect.stringContaining(`tests${path.sep}folder`)], + testIds: undefined + }) + }, + ]); }); test('should show error message', async ({ activate }) => { @@ -321,6 +368,19 @@ test('should only create test run if file belongs to context', async ({ activate tests2> playwright list-files -c playwright.config.js tests1> playwright test -c playwright.config.js test1.spec.ts `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { method: 'runGlobalSetup', params: {} }, + { + method: 'runTests', + params: expect.objectContaining({ + locations: [expect.stringContaining(`tests1${path.sep}test1\\.spec\\.ts`)], + testIds: undefined + }) + }, + { method: 'listFiles', params: {} }, + ]); + vscode.connectionLog.length = 0; { testRuns = []; @@ -335,6 +395,17 @@ test('should only create test run if file belongs to context', async ({ activate tests1> playwright test -c playwright.config.js test1.spec.ts tests2> playwright test -c playwright.config.js test2.spec.ts `); + await expect(vscode).toHaveConnectionLog([ + { method: 'runGlobalSetup', params: {} }, + { + method: 'runTests', + params: expect.objectContaining({ + locations: [expect.stringContaining(`tests2${path.sep}test2\\.spec\\.ts`)], + testIds: undefined + }) + }, + ]); + }); test('should only create test run if folder belongs to context', async ({ activate }) => { @@ -373,6 +444,18 @@ test('should only create test run if folder belongs to context', async ({ activa tests2> playwright list-files -c playwright.config.js tests1> playwright test -c playwright.config.js foo1 `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { method: 'listFiles', params: {} }, + { method: 'runGlobalSetup', params: {} }, + { + method: 'runTests', + params: expect.objectContaining({ + locations: [expect.stringContaining(`tests1${path.sep}foo1`)], + testIds: undefined + }) + }, + ]); }); test('should run all projects at once', async ({ activate }) => { @@ -398,6 +481,18 @@ test('should run all projects at once', async ({ activate }) => { > playwright list-files -c playwright.config.js > playwright test -c playwright.config.js `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { method: 'runGlobalSetup', params: {} }, + { + method: 'runTests', + params: expect.objectContaining({ + locations: [], + projects: [], + testIds: undefined + }) + }, + ]); }); test('should group projects by config', async ({ activate }) => { @@ -454,6 +549,26 @@ test('should group projects by config', async ({ activate }) => { tests1> playwright test -c playwright.config.js tests2> playwright test -c playwright.config.js `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { method: 'listFiles', params: {} }, + { method: 'runGlobalSetup', params: {} }, + { + method: 'runTests', + params: expect.objectContaining({ + locations: [], + testIds: undefined + }) + }, + { method: 'runGlobalSetup', params: {} }, + { + method: 'runTests', + params: expect.objectContaining({ + locations: [], + testIds: undefined + }) + }, + ]); }); test('should stop', async ({ activate, showBrowser }) => { @@ -584,6 +699,27 @@ test('should run all parametrized tests', async ({ activate }) => { > playwright test -c playwright.config.js --list --reporter=null tests/test.spec.ts > playwright test -c playwright.config.js tests/test.spec.ts:4 `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { + method: 'listTests', + params: expect.objectContaining({ + locations: [expect.stringContaining(`tests${path.sep}test\\.spec\\.ts`)], + }) + }, + { method: 'runGlobalSetup', params: {} }, + { + method: 'runTests', + params: expect.objectContaining({ + locations: undefined, + testIds: [ + expect.any(String), + expect.any(String), + expect.any(String), + ] + }) + }, + ]); }); test('should run one parametrized test', async ({ activate }) => { @@ -614,6 +750,20 @@ test('should run one parametrized test', async ({ activate }) => { > 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 `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { method: 'listTests', params: { + locations: [expect.stringContaining(`tests${path.sep}test\\.spec\\.ts`)] + } }, + { method: 'runGlobalSetup', params: {} }, + { + method: 'runTests', + params: expect.objectContaining({ + locations: undefined, + testIds: [expect.any(String)] + }) + }, + ]); }); test('should run one parametrized groups', async ({ activate }) => { @@ -652,6 +802,26 @@ test('should run one parametrized groups', async ({ activate }) => { > 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 `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { + method: 'listTests', + params: expect.objectContaining({ + locations: [expect.stringContaining(`tests${path.sep}test\\.spec\\.ts`)], + }) + }, + { method: 'runGlobalSetup', params: {} }, + { + method: 'runTests', + params: expect.objectContaining({ + locations: undefined, + testIds: [ + expect.any(String), + expect.any(String), + ] + }) + }, + ]); }); test('should run tests in parametrized groups', async ({ activate }) => { @@ -686,6 +856,26 @@ test('should run tests in parametrized groups', async ({ activate }) => { > 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 `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { + method: 'listTests', + params: expect.objectContaining({ + locations: [expect.stringContaining(`tests${path.sep}test\\.spec\\.ts`)], + }) + }, + { method: 'runGlobalSetup', params: {} }, + { + method: 'runTests', + params: expect.objectContaining({ + locations: undefined, + testIds: [ + expect.any(String), + ] + }) + }, + ]); + vscode.connectionLog.length = 0; const testItems2 = testController.findTestItems(/level 2/); expect(testItems2.length).toBe(1); @@ -704,6 +894,17 @@ test('should run tests in parametrized groups', async ({ activate }) => { > 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 `); + await expect(vscode).toHaveConnectionLog([ + { + method: 'runTests', + params: expect.objectContaining({ + locations: undefined, + testIds: [ + expect.any(String), + ] + }) + }, + ]); }); test('should list tests in relative folder', async ({ activate }) => { @@ -721,6 +922,15 @@ test('should list tests in relative folder', async ({ activate }) => { foo/bar> playwright list-files -c playwright.config.js foo/bar> playwright test -c playwright.config.js --list --reporter=null ../../tests/test.spec.ts `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { + method: 'listTests', + params: expect.objectContaining({ + locations: [expect.stringContaining(`tests${path.sep}test\\.spec\\.ts`)], + }) + }, + ]); await expect(testController).toHaveTestTree(` - tests @@ -761,6 +971,17 @@ test('should filter selected project', async ({ activate }) => { > playwright list-files -c playwright.config.js > playwright test -c playwright.config.js --project=project 1 tests1/test.spec.ts `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { method: 'runGlobalSetup', params: {} }, + { + method: 'runTests', + params: expect.objectContaining({ + projects: ['project 1'], + locations: [expect.stringContaining(`tests1${path.sep}test\\.spec\\.ts`)], + }) + }, + ]); }); test('should report project-specific failures', async ({ activate }) => { diff --git a/tests/source-map.spec.ts b/tests/source-map.spec.ts index 94a20e877..920b7cd07 100644 --- a/tests/source-map.spec.ts +++ b/tests/source-map.spec.ts @@ -15,6 +15,7 @@ */ import { expect, test } from './utils'; +import path from 'path'; test('should list files', async ({ activate }) => { const { vscode, testController } = await activate({ @@ -30,6 +31,9 @@ test('should list files', async ({ activate }) => { await expect(vscode).toHaveExecLog(` > playwright list-files -c playwright.config.js `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + ]); }); test('should list tests on expand', async ({ activate }) => { @@ -52,6 +56,15 @@ test('should list tests on expand', async ({ activate }) => { > playwright list-files -c playwright.config.js > playwright test -c playwright.config.js --list --reporter=null tests/test.spec.ts `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { + method: 'listTests', + params: expect.objectContaining({ + locations: [expect.stringContaining(`tests${path.sep}test\\.spec\\.ts`)], + }) + }, + ]); }); test('should list tests for visible editors', async ({ activate }) => { @@ -76,6 +89,15 @@ test('should list tests for visible editors', async ({ activate }) => { > playwright list-files -c playwright.config.js > playwright test -c playwright.config.js --list --reporter=null tests/test.spec.ts `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { + method: 'listTests', + params: expect.objectContaining({ + locations: [expect.stringContaining('test\\.spec\\.ts')], + }) + }, + ]); }); test('should pick new files', async ({ activate }) => { @@ -112,6 +134,10 @@ test('should pick new files', async ({ activate }) => { > playwright list-files -c playwright.config.js > playwright list-files -c playwright.config.js `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { method: 'listFiles', params: {} }, + ]); }); test('should remove deleted files', async ({ activate }) => { @@ -138,6 +164,9 @@ test('should remove deleted files', async ({ activate }) => { await expect(vscode).toHaveExecLog(` > playwright list-files -c playwright.config.js `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + ]); await Promise.all([ new Promise(f => testController.onDidChangeTestItem(f)), @@ -156,6 +185,10 @@ test('should remove deleted files', async ({ activate }) => { > playwright list-files -c playwright.config.js > playwright list-files -c playwright.config.js `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { method: 'listFiles', params: {} }, + ]); }); test('should discover new tests', async ({ activate }) => { @@ -172,6 +205,16 @@ test('should discover new tests', async ({ activate }) => { > playwright list-files -c playwright.config.js > playwright test -c playwright.config.js --list --reporter=null tests/test.spec.ts `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { + method: 'listTests', + params: expect.objectContaining({ + locations: [expect.stringContaining(`tests${path.sep}test\\.spec\\.ts`)], + }) + }, + ]); + vscode.commandLog.length = 0; await Promise.all([ new Promise(f => testController.onDidChangeTestItem(f)), @@ -193,6 +236,22 @@ test('should discover new tests', async ({ activate }) => { > 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 `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { + method: 'listTests', + params: expect.objectContaining({ + locations: [expect.stringContaining(`tests${path.sep}test\\.spec\\.ts`)], + }) + }, + { + method: 'listTests', + params: expect.objectContaining({ + locations: [expect.stringContaining(`tests${path.sep}test\\.spec\\.ts`)], + }) + }, + ]); + }); test('should run all tests', async ({ activate }) => { @@ -219,6 +278,17 @@ test('should run all tests', async ({ activate }) => { > playwright list-files -c playwright.config.js > playwright test -c playwright.config.js `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { method: 'runGlobalSetup', params: {} }, + { + method: 'runTests', + params: expect.objectContaining({ + locations: [], + testIds: undefined + }) + }, + ]); }); test('should run one test', async ({ activate }) => { @@ -246,6 +316,25 @@ test('should run one test', async ({ activate }) => { > playwright test -c playwright.config.js --list --reporter=null tests/test.spec.ts > playwright test -c playwright.config.js tests/test.spec.ts:3 `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { + method: 'listTests', + params: expect.objectContaining({ + locations: [expect.stringContaining(`tests${path.sep}test\\.spec\\.ts`)], + }) + }, + { method: 'runGlobalSetup', params: {} }, + { + method: 'runTests', + params: expect.objectContaining({ + locations: undefined, + testIds: [ + expect.any(String), + ] + }) + }, + ]); }); diff --git a/tests/track-configs.spec.ts b/tests/track-configs.spec.ts index a7d4b5f5b..d57719ac1 100644 --- a/tests/track-configs.spec.ts +++ b/tests/track-configs.spec.ts @@ -35,6 +35,9 @@ test('should load first config', async ({ activate }) => { await expect(vscode).toHaveExecLog(` > playwright list-files -c playwright.config.js `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + ]); }); test('should load second config', async ({ activate }) => { @@ -69,6 +72,11 @@ test('should load second config', async ({ activate }) => { > playwright list-files -c playwright1.config.js > playwright list-files -c playwright2.config.js `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { method: 'listFiles', params: {} }, + { method: 'listFiles', params: {} }, + ]); }); test('should remove model for config', async ({ activate }) => { @@ -106,4 +114,9 @@ test('should remove model for config', async ({ activate }) => { > playwright list-files -c playwright2.config.js > playwright list-files -c playwright2.config.js `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { method: 'listFiles', params: {} }, + { method: 'listFiles', params: {} }, + ]); }); diff --git a/tests/utils.ts b/tests/utils.ts index 56daa0b90..8980544d7 100644 --- a/tests/utils.ts +++ b/tests/utils.ts @@ -91,6 +91,23 @@ export const expect = baseExpect.extend({ } }, + async toHaveConnectionLog(vscode: VSCode, expectedLog: any[]) { + if (!vscode.extensions[0]._settingsModel.useTestServer.get()) + return { pass: true, message: () => '' }; + const filterCommands = new Set(['ping', 'initialize']); + const filteredLog = () => { + return vscode.connectionLog.filter(e => !filterCommands.has(e.method)); + }; + try { + await expect.poll(() => filteredLog()).toEqual(expectedLog); + return { pass: true, message: () => '' }; + } catch (e) { + return { + pass: false, + message: () => e.toString() + }; + } + }, }); export const test = baseTest.extend({ diff --git a/tests/watch.spec.ts b/tests/watch.spec.ts index 09c8319eb..8b235de4d 100644 --- a/tests/watch.spec.ts +++ b/tests/watch.spec.ts @@ -16,6 +16,7 @@ import { TestRun } from './mock/vscode'; import { expect, test } from './utils'; +import path from 'path'; test.beforeEach(async ({ vscode }) => { const configuration = vscode.workspace.getConfiguration('playwright'); @@ -58,6 +59,20 @@ test('should watch all tests', async ({ activate }) => { > playwright find-related-test-files -c playwright.config.js > playwright test -c playwright.config.js tests/test-1.spec.ts `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { method: 'findRelatedTestFiles', params: { + files: [expect.stringContaining(`tests${path.sep}test-1.spec.ts`)] + } }, + { method: 'runGlobalSetup', params: {} }, + { + method: 'runTests', + params: expect.objectContaining({ + locations: [expect.stringContaining(`tests${path.sep}test-1\\.spec\\.ts`)], + testIds: undefined + }) + }, + ]); }); test('should unwatch all tests', async ({ activate }) => { @@ -91,6 +106,9 @@ test('should unwatch all tests', async ({ activate }) => { await expect(vscode).toHaveExecLog(` > playwright list-files -c playwright.config.js `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + ]); }); test('should watch test file', async ({ activate }) => { @@ -170,6 +188,18 @@ test.skip('should watch tests via helper', async ({ activate }) => { > playwright find-related-test-files -c playwright.config.js > playwright test -c playwright.config.js tests/test.spec.ts `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { method: 'findRelatedTests', params: {} }, + { method: 'runGlobalSetup', params: {} }, + { + method: 'runTests', + params: expect.objectContaining({ + locations: [expect.stringContaining(`tests1${path.sep}test\\.spec\\.ts`)], + testIds: undefined + }) + }, + ]); }); test('should watch test in a file', async ({ activate }) => { @@ -215,6 +245,37 @@ test('should watch test in a file', async ({ activate }) => { > playwright find-related-test-files -c playwright.config.js > playwright test -c playwright.config.js tests/test.spec.ts:3 `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { + method: 'listTests', + params: expect.objectContaining({ + locations: [expect.stringContaining(`tests${path.sep}test\\.spec\\.ts`)], + }) + }, + { + method: 'listTests', + params: expect.objectContaining({ + locations: [expect.stringContaining(`tests${path.sep}test\\.spec\\.ts`)], + }) + }, + { + method: 'findRelatedTestFiles', + params: { + files: [expect.stringContaining(`tests${path.sep}test.spec.ts`)], + } + }, + { method: 'runGlobalSetup', params: {} }, + { + method: 'runTests', + params: expect.objectContaining({ + locations: undefined, + testIds: [ + expect.any(String) + ] + }) + }, + ]); }); test('should watch two tests in a file', async ({ activate }) => { @@ -265,4 +326,36 @@ test('should watch two tests in a file', async ({ activate }) => { > playwright find-related-test-files -c playwright.config.js > playwright test -c playwright.config.js tests/test.spec.ts:3 tests/test.spec.ts:4 `); + await expect(vscode).toHaveConnectionLog([ + { method: 'listFiles', params: {} }, + { + method: 'listTests', + params: expect.objectContaining({ + locations: [expect.stringContaining(`tests${path.sep}test\\.spec\\.ts`)], + }) + }, + { + method: 'listTests', + params: expect.objectContaining({ + locations: [expect.stringContaining(`tests${path.sep}test\\.spec\\.ts`)], + }) + }, + { + method: 'findRelatedTestFiles', + params: { + files: [expect.stringContaining(`tests${path.sep}test.spec.ts`)], + } + }, + { method: 'runGlobalSetup', params: {} }, + { + method: 'runTests', + params: expect.objectContaining({ + locations: undefined, + testIds: [ + expect.any(String), + expect.any(String), + ] + }) + }, + ]); });