From 4c4085e105822c7957e5aef3fab05bfc17566686 Mon Sep 17 00:00:00 2001 From: Pavel Feldman Date: Fri, 12 May 2023 19:15:31 -0700 Subject: [PATCH] chore: partially hide built-in fixture steps (#23005) --- .../playwright-test/src/common/fixtures.ts | 11 ++- packages/playwright-test/src/index.ts | 15 ++-- packages/playwright-test/src/util.ts | 12 ++- .../src/worker/fixtureRunner.ts | 11 ++- packages/trace-viewer/src/ui/modelUtil.ts | 9 ++- packages/trace-viewer/src/ui/workbench.tsx | 2 +- tests/playwright-test/expect-to-pass.spec.ts | 2 +- .../playwright-test/playwright.reuse.spec.ts | 1 + .../playwright-test/playwright.trace.spec.ts | 8 +- tests/playwright-test/reporter.spec.ts | 36 ++++----- tests/playwright-test/test-step.spec.ts | 80 +++++++++++-------- .../to-have-screenshot.spec.ts | 2 +- .../ui-mode-test-progress.spec.ts | 1 - tests/playwright-test/ui-mode-trace.spec.ts | 3 - 14 files changed, 115 insertions(+), 78 deletions(-) diff --git a/packages/playwright-test/src/common/fixtures.ts b/packages/playwright-test/src/common/fixtures.ts index 4fd298e7cc..e03da64c20 100644 --- a/packages/playwright-test/src/common/fixtures.ts +++ b/packages/playwright-test/src/common/fixtures.ts @@ -49,6 +49,8 @@ export type FixtureRegistration = { super?: FixtureRegistration; // Whether this fixture is an option override value set from the config. optionOverride?: boolean; + // Do not generate the step for this fixture. + hideStep?: boolean; }; export type LoadError = { message: string; @@ -101,7 +103,7 @@ export class FixturePool { for (const entry of Object.entries(fixtures)) { const name = entry[0]; let value = entry[1]; - let options: { auto: FixtureAuto, scope: FixtureScope, option: boolean, timeout: number | undefined, customTitle: string | undefined } | undefined; + let options: { auto: FixtureAuto, scope: FixtureScope, option: boolean, timeout: number | undefined, customTitle: string | undefined, hideStep: boolean | undefined } | undefined; if (isFixtureTuple(value)) { options = { auto: value[1].auto ?? false, @@ -109,6 +111,7 @@ export class FixturePool { option: !!value[1].option, timeout: value[1].timeout, customTitle: (value[1] as any)._title, + hideStep: (value[1] as any)._hideStep, }; value = value[0]; } @@ -125,9 +128,9 @@ export class FixturePool { continue; } } else if (previous) { - options = { auto: previous.auto, scope: previous.scope, option: previous.option, timeout: previous.timeout, customTitle: previous.customTitle }; + options = { auto: previous.auto, scope: previous.scope, option: previous.option, timeout: previous.timeout, customTitle: previous.customTitle, hideStep: undefined }; } else if (!options) { - options = { auto: false, scope: 'test', option: false, timeout: undefined, customTitle: undefined }; + options = { auto: false, scope: 'test', option: false, timeout: undefined, customTitle: undefined, hideStep: undefined }; } if (!kScopeOrder.includes(options.scope)) { @@ -149,7 +152,7 @@ export class FixturePool { } const deps = fixtureParameterNames(fn, location, e => this._onLoadError(e)); - const registration: FixtureRegistration = { id: '', name, location, scope: options.scope, fn, auto: options.auto, option: options.option, timeout: options.timeout, customTitle: options.customTitle, deps, super: previous, optionOverride: isOptionsOverride }; + const registration: FixtureRegistration = { id: '', name, location, scope: options.scope, fn, auto: options.auto, option: options.option, timeout: options.timeout, customTitle: options.customTitle, hideStep: options.hideStep, deps, super: previous, optionOverride: isOptionsOverride }; registrationId(registration); this.registrations.set(name, registration); } diff --git a/packages/playwright-test/src/index.ts b/packages/playwright-test/src/index.ts index 0128ba2339..4a0f88f8d8 100644 --- a/packages/playwright-test/src/index.ts +++ b/packages/playwright-test/src/index.ts @@ -64,7 +64,7 @@ const playwrightFixtures: Fixtures = ({ browserName: [({ defaultBrowserType }, use) => use(defaultBrowserType), { scope: 'worker', option: true }], playwright: [async ({}, use) => { await use(require('playwright-core')); - }, { scope: 'worker' }], + }, { scope: 'worker', _hideStep: true } as any], headless: [({ launchOptions }, use) => use(launchOptions.headless ?? true), { scope: 'worker', option: true }], channel: [({ launchOptions }, use) => use(launchOptions.channel), { scope: 'worker', option: true }], launchOptions: [{}, { scope: 'worker', option: true }], @@ -131,13 +131,17 @@ const playwrightFixtures: Fixtures = ({ }, }); await use(browser); - await browser.close(); + await (browser as any)._wrapApiCall(async () => { + await browser.close(); + }, true); return; } const browser = await playwright[browserName].launch(); await use(browser); - await browser.close(); + await (browser as any)._wrapApiCall(async () => { + await browser.close(); + }, true); }, { scope: 'worker', timeout: 0 }], acceptDownloads: [({ contextOptions }, use) => use(contextOptions.acceptDownloads ?? true), { option: true }], @@ -383,8 +387,9 @@ const playwrightFixtures: Fixtures = ({ let counter = 0; await Promise.all([...contexts.keys()].map(async context => { (context as any)[kStartedContextTearDown] = true; - await context.close(); - + await (context as any)._wrapApiCall(async () => { + await context.close(); + }, true); const testFailed = testInfo.status !== testInfo.expectedStatus; const preserveVideo = captureVideo && (videoMode === 'on' || (testFailed && videoMode === 'retain-on-failure') || (videoMode === 'on-first-retry' && testInfo.retry === 1)); if (preserveVideo) { diff --git a/packages/playwright-test/src/util.ts b/packages/playwright-test/src/util.ts index a03d6453c1..e2d0f14c39 100644 --- a/packages/playwright-test/src/util.ts +++ b/packages/playwright-test/src/util.ts @@ -40,15 +40,21 @@ export function filterStackTrace(e: Error): { message: string, stack: string } { }; } +export function filterStackFile(file: string) { + if (!process.env.PWDEBUGIMPL && file.startsWith(PLAYWRIGHT_TEST_PATH)) + return false; + if (!process.env.PWDEBUGIMPL && file.startsWith(PLAYWRIGHT_CORE_PATH)) + return false; + return true; +} + export function filteredStackTrace(rawStack: RawStack): StackFrame[] { const frames: StackFrame[] = []; for (const line of rawStack) { const frame = parseStackTraceLine(line); if (!frame || !frame.file) continue; - if (!process.env.PWDEBUGIMPL && frame.file.startsWith(PLAYWRIGHT_TEST_PATH)) - continue; - if (!process.env.PWDEBUGIMPL && frame.file.startsWith(PLAYWRIGHT_CORE_PATH)) + if (!filterStackFile(frame.file)) continue; frames.push(frame); } diff --git a/packages/playwright-test/src/worker/fixtureRunner.ts b/packages/playwright-test/src/worker/fixtureRunner.ts index c01093b8bb..04f311eeb0 100644 --- a/packages/playwright-test/src/worker/fixtureRunner.ts +++ b/packages/playwright-test/src/worker/fixtureRunner.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { formatLocation, debugTest } from '../util'; +import { formatLocation, debugTest, filterStackFile, serializeError } from '../util'; import { ManualPromise, zones } from 'playwright-core/lib/utils'; import type { TestInfoImpl, TestStepInternal } from './testInfo'; import type { FixtureDescription, TimeoutManager } from './timeoutManager'; @@ -76,7 +76,8 @@ class Fixture { // Break the regustration function into before/after steps. Create these before/after stacks // w/o scopes, and create single mutable step that will be converted into the after step. - const shouldGenerateStep = !this.registration.name.startsWith('_') && !this.registration.option && this.registration.scope === 'test'; + const shouldGenerateStep = !this.registration.hideStep && !this.registration.name.startsWith('_') && !this.registration.option; + const isInternalFixture = this.registration.location && filterStackFile(this.registration.location.file); let mutableStepOnStack: TestStepInternal | undefined; let afterStep: TestStepInternal | undefined; @@ -97,6 +98,7 @@ class Fixture { wallTime: Date.now(), title: `fixture: ${this.registration.name}`, category: 'fixture', + location: isInternalFixture ? this.registration.location : undefined, }, testInfo._afterHooksStep); mutableStepOnStack!.stepId = afterStep.stepId; } @@ -121,6 +123,7 @@ class Fixture { await testInfo._runAsStep({ title: `fixture: ${this.registration.name}`, category: 'fixture', + location: isInternalFixture ? this.registration.location : undefined, }, async step => { mutableStepOnStack = step; return await this.registration.fn(params, useFunc, info); @@ -137,8 +140,10 @@ class Fixture { await useFuncStarted; if (shouldGenerateStep) { mutableStepOnStack?.complete({}); - this._selfTeardownComplete?.finally(() => { + this._selfTeardownComplete?.then(() => { afterStep?.complete({}); + }).catch(e => { + afterStep?.complete({ error: serializeError(e) }); }); } testInfo._timeoutManager.setCurrentFixture(undefined); diff --git a/packages/trace-viewer/src/ui/modelUtil.ts b/packages/trace-viewer/src/ui/modelUtil.ts index 41a91c5a5e..30f0b11831 100644 --- a/packages/trace-viewer/src/ui/modelUtil.ts +++ b/packages/trace-viewer/src/ui/modelUtil.ts @@ -131,7 +131,14 @@ function mergeActions(contexts: ContextEntry[]) { } const result = [...map.values()]; - result.sort((a1, a2) => a1.wallTime - a2.wallTime); + result.sort((a1, a2) => { + if (a2.parentId === a1.callId) + return -1; + if (a1.parentId === a2.callId) + return 1; + return a1.wallTime - a2.wallTime || a1.startTime - a2.startTime; + }); + for (let i = 1; i < result.length; ++i) (result[i] as any)[prevInListSymbol] = result[i - 1]; diff --git a/packages/trace-viewer/src/ui/workbench.tsx b/packages/trace-viewer/src/ui/workbench.tsx index 025501345e..883058054f 100644 --- a/packages/trace-viewer/src/ui/workbench.tsx +++ b/packages/trace-viewer/src/ui/workbench.tsx @@ -74,7 +74,7 @@ export const Workbench: React.FunctionComponent<{ const callTab: TabbedPaneTabModel = { id: 'call', - title: showSourcesFirst ? 'Log' : 'Call', + title: 'Call', render: () => }; const sourceTab: TabbedPaneTabModel = { diff --git a/tests/playwright-test/expect-to-pass.spec.ts b/tests/playwright-test/expect-to-pass.spec.ts index 06e36a4c1c..37bb8c7460 100644 --- a/tests/playwright-test/expect-to-pass.spec.ts +++ b/tests/playwright-test/expect-to-pass.spec.ts @@ -192,7 +192,7 @@ test('should not spin forever', async ({ runInlineTest }) => { expect(() => { log?.push('poll'); throw new Error('Polling'); - }).toPass().catch(); + }).toPass().catch(() => {}); }); test('should not see toPass', async () => { log = []; diff --git a/tests/playwright-test/playwright.reuse.spec.ts b/tests/playwright-test/playwright.reuse.spec.ts index aea83b64f9..0bf77686ae 100644 --- a/tests/playwright-test/playwright.reuse.spec.ts +++ b/tests/playwright-test/playwright.reuse.spec.ts @@ -146,6 +146,7 @@ test('should reuse context with trace if mode=when-possible', async ({ runInline const trace1 = await parseTrace(testInfo.outputPath('test-results', 'reuse-one', 'trace.zip')); expect(trace1.apiNames).toEqual([ 'Before Hooks', + 'fixture: browser', 'browserType.launch', 'fixture: context', 'fixture: page', diff --git a/tests/playwright-test/playwright.trace.spec.ts b/tests/playwright-test/playwright.trace.spec.ts index 42123e9c95..0fc8d072c2 100644 --- a/tests/playwright-test/playwright.trace.spec.ts +++ b/tests/playwright-test/playwright.trace.spec.ts @@ -92,6 +92,7 @@ test('should record api trace', async ({ runInlineTest, server }, testInfo) => { 'fixture: request', 'apiRequest.newContext', 'tracing.start', + 'fixture: browser', 'browserType.launch', 'fixture: context', 'browser.newContext', @@ -103,7 +104,6 @@ test('should record api trace', async ({ runInlineTest, server }, testInfo) => { 'After Hooks', 'fixture: page', 'fixture: context', - 'browserContext.close', 'fixture: request', 'tracing.stopChunk', 'apiRequestContext.dispose', @@ -135,11 +135,9 @@ test('should record api trace', async ({ runInlineTest, server }, testInfo) => { 'After Hooks', 'fixture: page', 'fixture: context', - 'browserContext.close', 'fixture: request', 'tracing.stopChunk', 'apiRequestContext.dispose', - 'browser.close', 'tracing.stopChunk', ]); }); @@ -328,6 +326,7 @@ test('should not override trace file in afterAll', async ({ runInlineTest, serve expect(trace1.apiNames).toEqual([ 'Before Hooks', + 'fixture: browser', 'browserType.launch', 'fixture: context', 'browser.newContext', @@ -338,7 +337,6 @@ test('should not override trace file in afterAll', async ({ runInlineTest, serve 'After Hooks', 'fixture: page', 'fixture: context', - 'browserContext.close', 'afterAll hook', 'fixture: request', 'apiRequest.newContext', @@ -347,7 +345,7 @@ test('should not override trace file in afterAll', async ({ runInlineTest, serve 'fixture: request', 'tracing.stopChunk', 'apiRequestContext.dispose', - 'browser.close', + 'fixture: browser', ]); const error = await parseTrace(testInfo.outputPath('test-results', 'a-test-2', 'trace.zip')).catch(e => e); diff --git a/tests/playwright-test/reporter.spec.ts b/tests/playwright-test/reporter.spec.ts index c8e3984c40..aecc6b9838 100644 --- a/tests/playwright-test/reporter.spec.ts +++ b/tests/playwright-test/reporter.spec.ts @@ -278,8 +278,10 @@ test('should report expect steps', async ({ runInlineTest }) => { `begin {\"title\":\"After Hooks\",\"category\":\"hook\"}`, `end {\"title\":\"After Hooks\",\"category\":\"hook\"}`, `begin {\"title\":\"Before Hooks\",\"category\":\"hook\"}`, + `begin {\"title\":\"fixture: browser\",\"category\":\"fixture\"}`, `begin {\"title\":\"browserType.launch\",\"category\":\"pw:api\"}`, `end {\"title\":\"browserType.launch\",\"category\":\"pw:api\"}`, + `end {\"title\":\"fixture: browser\",\"category\":\"fixture\",\"steps\":[{\"title\":\"browserType.launch\",\"category\":\"pw:api\"}]}`, `begin {\"title\":\"fixture: context\",\"category\":\"fixture\"}`, `begin {\"title\":\"browser.newContext\",\"category\":\"pw:api\"}`, `end {\"title\":\"browser.newContext\",\"category\":\"pw:api\"}`, @@ -288,7 +290,7 @@ test('should report expect steps', async ({ runInlineTest }) => { `begin {\"title\":\"browserContext.newPage\",\"category\":\"pw:api\"}`, `end {\"title\":\"browserContext.newPage\",\"category\":\"pw:api\"}`, `end {\"title\":\"fixture: page\",\"category\":\"fixture\",\"steps\":[{\"title\":\"browserContext.newPage\",\"category\":\"pw:api\"}]}`, - `end {\"title\":\"Before Hooks\",\"category\":\"hook\",\"steps\":[{\"title\":\"browserType.launch\",\"category\":\"pw:api\"},{\"title\":\"fixture: context\",\"category\":\"fixture\",\"steps\":[{\"title\":\"browser.newContext\",\"category\":\"pw:api\"}]},{\"title\":\"fixture: page\",\"category\":\"fixture\",\"steps\":[{\"title\":\"browserContext.newPage\",\"category\":\"pw:api\"}]}]}`, + `end {\"title\":\"Before Hooks\",\"category\":\"hook\",\"steps\":[{\"title\":\"fixture: browser\",\"category\":\"fixture\",\"steps\":[{\"title\":\"browserType.launch\",\"category\":\"pw:api\"}]},{\"title\":\"fixture: context\",\"category\":\"fixture\",\"steps\":[{\"title\":\"browser.newContext\",\"category\":\"pw:api\"}]},{\"title\":\"fixture: page\",\"category\":\"fixture\",\"steps\":[{\"title\":\"browserContext.newPage\",\"category\":\"pw:api\"}]}]}`, `begin {\"title\":\"expect.not.toHaveTitle\",\"category\":\"expect\"}`, `end {\"title\":\"expect.not.toHaveTitle\",\"category\":\"expect\"}`, `begin {\"title\":\"After Hooks\",\"category\":\"hook\"}`, @@ -296,9 +298,7 @@ test('should report expect steps', async ({ runInlineTest }) => { `end {\"title\":\"fixture: page\",\"category\":\"fixture\"}`, `begin {\"title\":\"fixture: context\",\"category\":\"fixture\"}`, `end {\"title\":\"fixture: context\",\"category\":\"fixture\"}`, - `begin {\"title\":\"browserContext.close\",\"category\":\"pw:api\"}`, - `end {\"title\":\"browserContext.close\",\"category\":\"pw:api\"}`, - `end {\"title\":\"After Hooks\",\"category\":\"hook\",\"steps\":[{\"title\":\"fixture: page\",\"category\":\"fixture\"},{\"title\":\"fixture: context\",\"category\":\"fixture\"},{\"title\":\"browserContext.close\",\"category\":\"pw:api\"}]}`, + `end {\"title\":\"After Hooks\",\"category\":\"hook\",\"steps\":[{\"title\":\"fixture: page\",\"category\":\"fixture\"},{\"title\":\"fixture: context\",\"category\":\"fixture\"}]}`, ]); }); @@ -347,8 +347,10 @@ test('should report api steps', async ({ runInlineTest }) => { expect(result.exitCode).toBe(0); expect(result.outputLines).toEqual([ `begin {\"title\":\"Before Hooks\",\"category\":\"hook\"}`, + `begin {\"title\":\"fixture: browser\",\"category\":\"fixture\"}`, `begin {\"title\":\"browserType.launch\",\"category\":\"pw:api\"}`, `end {\"title\":\"browserType.launch\",\"category\":\"pw:api\"}`, + `end {\"title\":\"fixture: browser\",\"category\":\"fixture\",\"steps\":[{\"title\":\"browserType.launch\",\"category\":\"pw:api\"}]}`, `begin {\"title\":\"fixture: context\",\"category\":\"fixture\"}`, `begin {\"title\":\"browser.newContext\",\"category\":\"pw:api\"}`, `end {\"title\":\"browser.newContext\",\"category\":\"pw:api\"}`, @@ -361,7 +363,7 @@ test('should report api steps', async ({ runInlineTest }) => { `begin {\"title\":\"apiRequest.newContext\",\"category\":\"pw:api\"}`, `end {\"title\":\"apiRequest.newContext\",\"category\":\"pw:api\"}`, `end {\"title\":\"fixture: request\",\"category\":\"fixture\",\"steps\":[{\"title\":\"apiRequest.newContext\",\"category\":\"pw:api\"}]}`, - `end {\"title\":\"Before Hooks\",\"category\":\"hook\",\"steps\":[{\"title\":\"browserType.launch\",\"category\":\"pw:api\"},{\"title\":\"fixture: context\",\"category\":\"fixture\",\"steps\":[{\"title\":\"browser.newContext\",\"category\":\"pw:api\"}]},{\"title\":\"fixture: page\",\"category\":\"fixture\",\"steps\":[{\"title\":\"browserContext.newPage\",\"category\":\"pw:api\"}]},{\"title\":\"fixture: request\",\"category\":\"fixture\",\"steps\":[{\"title\":\"apiRequest.newContext\",\"category\":\"pw:api\"}]}]}`, + `end {\"title\":\"Before Hooks\",\"category\":\"hook\",\"steps\":[{\"title\":\"fixture: browser\",\"category\":\"fixture\",\"steps\":[{\"title\":\"browserType.launch\",\"category\":\"pw:api\"}]},{\"title\":\"fixture: context\",\"category\":\"fixture\",\"steps\":[{\"title\":\"browser.newContext\",\"category\":\"pw:api\"}]},{\"title\":\"fixture: page\",\"category\":\"fixture\",\"steps\":[{\"title\":\"browserContext.newPage\",\"category\":\"pw:api\"}]},{\"title\":\"fixture: request\",\"category\":\"fixture\",\"steps\":[{\"title\":\"apiRequest.newContext\",\"category\":\"pw:api\"}]}]}`, `begin {\"title\":\"page.waitForNavigation\",\"category\":\"pw:api\"}`, `begin {\"title\":\"page.goto(data:text/html,)\",\"category\":\"pw:api\"}`, `end {\"title\":\"page.waitForNavigation\",\"category\":\"pw:api\",\"steps\":[{\"title\":\"page.goto(data:text/html,)\",\"category\":\"pw:api\"}]}`, @@ -383,9 +385,7 @@ test('should report api steps', async ({ runInlineTest }) => { `end {\"title\":\"fixture: page\",\"category\":\"fixture\"}`, `begin {\"title\":\"fixture: context\",\"category\":\"fixture\"}`, `end {\"title\":\"fixture: context\",\"category\":\"fixture\"}`, - `begin {\"title\":\"browserContext.close\",\"category\":\"pw:api\"}`, - `end {\"title\":\"browserContext.close\",\"category\":\"pw:api\"}`, - `end {\"title\":\"After Hooks\",\"category\":\"hook\",\"steps\":[{\"title\":\"fixture: request\",\"category\":\"fixture\",\"steps\":[{\"title\":\"apiRequestContext.dispose\",\"category\":\"pw:api\"}]},{\"title\":\"fixture: page\",\"category\":\"fixture\"},{\"title\":\"fixture: context\",\"category\":\"fixture\"},{\"title\":\"browserContext.close\",\"category\":\"pw:api\"}]}`, + `end {\"title\":\"After Hooks\",\"category\":\"hook\",\"steps\":[{\"title\":\"fixture: request\",\"category\":\"fixture\",\"steps\":[{\"title\":\"apiRequestContext.dispose\",\"category\":\"pw:api\"}]},{\"title\":\"fixture: page\",\"category\":\"fixture\"},{\"title\":\"fixture: context\",\"category\":\"fixture\"}]}`, `begin {\"title\":\"Before Hooks\",\"category\":\"hook\"}`, `begin {\"title\":\"beforeAll hook\",\"category\":\"hook\"}`, `begin {\"title\":\"browser.newPage\",\"category\":\"pw:api\"}`, @@ -432,8 +432,10 @@ test('should report api step failure', async ({ runInlineTest }) => { expect(result.exitCode).toBe(1); expect(result.outputLines).toEqual([ `begin {\"title\":\"Before Hooks\",\"category\":\"hook\"}`, + `begin {\"title\":\"fixture: browser\",\"category\":\"fixture\"}`, `begin {\"title\":\"browserType.launch\",\"category\":\"pw:api\"}`, `end {\"title\":\"browserType.launch\",\"category\":\"pw:api\"}`, + `end {\"title\":\"fixture: browser\",\"category\":\"fixture\",\"steps\":[{\"title\":\"browserType.launch\",\"category\":\"pw:api\"}]}`, `begin {\"title\":\"fixture: context\",\"category\":\"fixture\"}`, `begin {\"title\":\"browser.newContext\",\"category\":\"pw:api\"}`, `end {\"title\":\"browser.newContext\",\"category\":\"pw:api\"}`, @@ -442,7 +444,7 @@ test('should report api step failure', async ({ runInlineTest }) => { `begin {\"title\":\"browserContext.newPage\",\"category\":\"pw:api\"}`, `end {\"title\":\"browserContext.newPage\",\"category\":\"pw:api\"}`, `end {\"title\":\"fixture: page\",\"category\":\"fixture\",\"steps\":[{\"title\":\"browserContext.newPage\",\"category\":\"pw:api\"}]}`, - `end {\"title\":\"Before Hooks\",\"category\":\"hook\",\"steps\":[{\"title\":\"browserType.launch\",\"category\":\"pw:api\"},{\"title\":\"fixture: context\",\"category\":\"fixture\",\"steps\":[{\"title\":\"browser.newContext\",\"category\":\"pw:api\"}]},{\"title\":\"fixture: page\",\"category\":\"fixture\",\"steps\":[{\"title\":\"browserContext.newPage\",\"category\":\"pw:api\"}]}]}`, + `end {\"title\":\"Before Hooks\",\"category\":\"hook\",\"steps\":[{\"title\":\"fixture: browser\",\"category\":\"fixture\",\"steps\":[{\"title\":\"browserType.launch\",\"category\":\"pw:api\"}]},{\"title\":\"fixture: context\",\"category\":\"fixture\",\"steps\":[{\"title\":\"browser.newContext\",\"category\":\"pw:api\"}]},{\"title\":\"fixture: page\",\"category\":\"fixture\",\"steps\":[{\"title\":\"browserContext.newPage\",\"category\":\"pw:api\"}]}]}`, `begin {\"title\":\"page.setContent\",\"category\":\"pw:api\"}`, `end {\"title\":\"page.setContent\",\"category\":\"pw:api\"}`, `begin {\"title\":\"page.click(input)\",\"category\":\"pw:api\"}`, @@ -452,11 +454,9 @@ test('should report api step failure', async ({ runInlineTest }) => { `end {\"title\":\"fixture: page\",\"category\":\"fixture\"}`, `begin {\"title\":\"fixture: context\",\"category\":\"fixture\"}`, `end {\"title\":\"fixture: context\",\"category\":\"fixture\"}`, - `begin {\"title\":\"browserContext.close\",\"category\":\"pw:api\"}`, - `end {\"title\":\"browserContext.close\",\"category\":\"pw:api\"}`, - `begin {\"title\":\"browser.close\",\"category\":\"pw:api\"}`, - `end {\"title\":\"browser.close\",\"category\":\"pw:api\"}`, - `end {\"title\":\"After Hooks\",\"category\":\"hook\",\"steps\":[{\"title\":\"fixture: page\",\"category\":\"fixture\"},{\"title\":\"fixture: context\",\"category\":\"fixture\"},{\"title\":\"browserContext.close\",\"category\":\"pw:api\"},{\"title\":\"browser.close\",\"category\":\"pw:api\"}]}`, + `begin {\"title\":\"fixture: browser\",\"category\":\"fixture\"}`, + `end {\"title\":\"fixture: browser\",\"category\":\"fixture\"}`, + `end {\"title\":\"After Hooks\",\"category\":\"hook\",\"steps\":[{\"title\":\"fixture: page\",\"category\":\"fixture\"},{\"title\":\"fixture: context\",\"category\":\"fixture\"},{\"title\":\"fixture: browser\",\"category\":\"fixture\"}]}`, ]); }); @@ -506,8 +506,10 @@ test('should show nice stacks for locators', async ({ runInlineTest }) => { expect(result.output).not.toContain('Internal error'); expect(result.outputLines).toEqual([ `begin {"title":"Before Hooks","category":"hook"}`, + `begin {\"title\":\"fixture: browser\",\"category\":\"fixture\"}`, `begin {\"title\":\"browserType.launch\",\"category\":\"pw:api\"}`, `end {\"title\":\"browserType.launch\",\"category\":\"pw:api\"}`, + `end {\"title\":\"fixture: browser\",\"category\":\"fixture\",\"steps\":[{\"title\":\"browserType.launch\",\"category\":\"pw:api\"}]}`, `begin {\"title\":\"fixture: context\",\"category\":\"fixture\"}`, `begin {\"title\":\"browser.newContext\",\"category\":\"pw:api\"}`, `end {\"title\":\"browser.newContext\",\"category\":\"pw:api\"}`, @@ -516,7 +518,7 @@ test('should show nice stacks for locators', async ({ runInlineTest }) => { `begin {"title":"browserContext.newPage","category":"pw:api"}`, `end {"title":"browserContext.newPage","category":"pw:api"}`, `end {\"title\":\"fixture: page\",\"category\":\"fixture\",\"steps\":[{\"title\":\"browserContext.newPage\",\"category\":\"pw:api\"}]}`, - `end {\"title\":\"Before Hooks\",\"category\":\"hook\",\"steps\":[{\"title\":\"browserType.launch\",\"category\":\"pw:api\"},{\"title\":\"fixture: context\",\"category\":\"fixture\",\"steps\":[{\"title\":\"browser.newContext\",\"category\":\"pw:api\"}]},{\"title\":\"fixture: page\",\"category\":\"fixture\",\"steps\":[{\"title\":\"browserContext.newPage\",\"category\":\"pw:api\"}]}]}`, + `end {\"title\":\"Before Hooks\",\"category\":\"hook\",\"steps\":[{\"title\":\"fixture: browser\",\"category\":\"fixture\",\"steps\":[{\"title\":\"browserType.launch\",\"category\":\"pw:api\"}]},{\"title\":\"fixture: context\",\"category\":\"fixture\",\"steps\":[{\"title\":\"browser.newContext\",\"category\":\"pw:api\"}]},{\"title\":\"fixture: page\",\"category\":\"fixture\",\"steps\":[{\"title\":\"browserContext.newPage\",\"category\":\"pw:api\"}]}]}`, `begin {"title":"page.setContent","category":"pw:api"}`, `end {"title":"page.setContent","category":"pw:api"}`, `begin {"title":"locator.evaluate(button)","category":"pw:api"}`, @@ -526,9 +528,7 @@ test('should show nice stacks for locators', async ({ runInlineTest }) => { `end {\"title\":\"fixture: page\",\"category\":\"fixture\"}`, `begin {\"title\":\"fixture: context\",\"category\":\"fixture\"}`, `end {\"title\":\"fixture: context\",\"category\":\"fixture\"}`, - `begin {"title":"browserContext.close","category":"pw:api"}`, - `end {"title":"browserContext.close","category":"pw:api"}`, - `end {\"title\":\"After Hooks\",\"category\":\"hook\",\"steps\":[{\"title\":\"fixture: page\",\"category\":\"fixture\"},{\"title\":\"fixture: context\",\"category\":\"fixture\"},{\"title\":\"browserContext.close\",\"category\":\"pw:api\"}]}`, + `end {\"title\":\"After Hooks\",\"category\":\"hook\",\"steps\":[{\"title\":\"fixture: page\",\"category\":\"fixture\"},{\"title\":\"fixture: context\",\"category\":\"fixture\"}]}`, ]); }); diff --git a/tests/playwright-test/test-step.spec.ts b/tests/playwright-test/test-step.spec.ts index ad3f5eeb4c..2f194b1a32 100644 --- a/tests/playwright-test/test-step.spec.ts +++ b/tests/playwright-test/test-step.spec.ts @@ -96,8 +96,14 @@ test('should report api step hierarchy', async ({ runInlineTest }) => { title: 'Before Hooks', steps: [ { - category: 'pw:api', - title: 'browserType.launch', + category: 'fixture', + title: 'fixture: browser', + steps: [ + { + category: 'pw:api', + title: 'browserType.launch', + }, + ] }, { category: 'fixture', @@ -191,10 +197,6 @@ test('should report api step hierarchy', async ({ runInlineTest }) => { category: 'fixture', title: 'fixture: context', }, - { - category: 'pw:api', - title: 'browserContext.close', - }, ], }, ]); @@ -271,8 +273,14 @@ test('should not report nested after hooks', async ({ runInlineTest }) => { title: 'Before Hooks', steps: [ { - category: 'pw:api', - title: 'browserType.launch', + category: 'fixture', + title: 'fixture: browser', + steps: [ + { + category: 'pw:api', + title: 'browserType.launch', + }, + ] }, { category: 'fixture', @@ -318,12 +326,8 @@ test('should not report nested after hooks', async ({ runInlineTest }) => { title: 'fixture: context', }, { - category: 'pw:api', - title: 'browserContext.close', - }, - { - category: 'pw:api', - title: 'browser.close', + category: 'fixture', + title: 'fixture: browser', }, ], }, @@ -414,8 +418,14 @@ test('should report expect step locations', async ({ runInlineTest }) => { title: 'Before Hooks', steps: [ { - category: 'pw:api', - title: 'browserType.launch', + category: 'fixture', + title: 'fixture: browser', + steps: [ + { + category: 'pw:api', + title: 'browserType.launch', + }, + ] }, { category: 'fixture', @@ -460,10 +470,6 @@ test('should report expect step locations', async ({ runInlineTest }) => { category: 'fixture', title: 'fixture: context', }, - { - category: 'pw:api', - title: 'browserContext.close', - }, ], }, ]); @@ -682,8 +688,14 @@ test('should nest steps based on zones', async ({ runInlineTest }) => { location: { file: 'a.test.ts', line: 'number', column: 'number' } }, { - title: 'browserType.launch', - category: 'pw:api' + category: 'fixture', + title: 'fixture: browser', + steps: [ + { + category: 'pw:api', + title: 'browserType.launch', + }, + ] }, { category: 'fixture', @@ -784,10 +796,6 @@ test('should nest steps based on zones', async ({ runInlineTest }) => { category: 'fixture', title: 'fixture: context', }, - { - title: 'browserContext.close', - category: 'pw:api' - }, { title: 'afterAll hook', category: 'hook', @@ -850,8 +858,11 @@ test('should not mark page.close as failed when page.click fails', async ({ runI }, steps: [ { - category: 'pw:api', - title: 'browserType.launch', + category: 'fixture', + title: 'fixture: browser', + steps: [ + { title: 'browserType.launch', category: 'pw:api' }, + ] }, { category: 'pw:api', @@ -911,8 +922,8 @@ test('should not mark page.close as failed when page.click fails', async ({ runI ], }, { - category: 'pw:api', - title: 'browser.close', + category: 'fixture', + title: 'fixture: browser', }, ], }, @@ -939,7 +950,13 @@ test('should nest page.continue insize page.goto steps', async ({ runInlineTest title: 'Before Hooks', category: 'hook', steps: [ - { title: 'browserType.launch', category: 'pw:api' }, + { + category: 'fixture', + title: 'fixture: browser', + steps: [ + { title: 'browserType.launch', category: 'pw:api' }, + ] + }, { category: 'fixture', title: 'fixture: context', @@ -991,7 +1008,6 @@ test('should nest page.continue insize page.goto steps', async ({ runInlineTest category: 'fixture', title: 'fixture: context', }, - { title: 'browserContext.close', category: 'pw:api' }, ], }, ]); diff --git a/tests/playwright-test/to-have-screenshot.spec.ts b/tests/playwright-test/to-have-screenshot.spec.ts index 133694c2c1..c1a9ab7a2b 100644 --- a/tests/playwright-test/to-have-screenshot.spec.ts +++ b/tests/playwright-test/to-have-screenshot.spec.ts @@ -207,6 +207,7 @@ test('should report toHaveScreenshot step with expectation name in title', async expect(result.exitCode).toBe(0); expect(result.outputLines).toEqual([ `end browserType.launch`, + `end fixture: browser`, `end browser.newContext`, `end fixture: context`, `end browserContext.newPage`, @@ -216,7 +217,6 @@ test('should report toHaveScreenshot step with expectation name in title', async `end expect.toHaveScreenshot(is-a-test-1.png)`, `end fixture: page`, `end fixture: context`, - `end browserContext.close`, `end After Hooks`, ]); }); diff --git a/tests/playwright-test/ui-mode-test-progress.spec.ts b/tests/playwright-test/ui-mode-test-progress.spec.ts index 949097bcb9..0197d89798 100644 --- a/tests/playwright-test/ui-mode-test-progress.spec.ts +++ b/tests/playwright-test/ui-mode-test-progress.spec.ts @@ -109,7 +109,6 @@ test('should update trace live', async ({ runUITest, server }) => { /After Hooks[\d.]+m?s/, /fixture: page[\d.]+m?s/, /fixture: context[\d.]+m?s/, - /browserContext.close[\d.]+m?s/, ]); }); diff --git a/tests/playwright-test/ui-mode-trace.spec.ts b/tests/playwright-test/ui-mode-trace.spec.ts index c7e9c08f34..6330e6f786 100644 --- a/tests/playwright-test/ui-mode-trace.spec.ts +++ b/tests/playwright-test/ui-mode-trace.spec.ts @@ -46,7 +46,6 @@ test('should merge trace events', async ({ runUITest, server }) => { /After Hooks[\d.]+m?s/, /fixture: page[\d.]+m?s/, /fixture: context[\d.]+m?s/, - /browserContext.close[\d.]+m?s/, ]); }); @@ -74,7 +73,6 @@ test('should merge web assertion events', async ({ runUITest }, testInfo) => { /After Hooks[\d.]+m?s/, /fixture: page[\d.]+m?s/, /fixture: context[\d.]+m?s/, - /browserContext.close[\d.]+m?s/, ]); }); @@ -149,7 +147,6 @@ test('should show snapshots for sync assertions', async ({ runUITest, server }) /After Hooks[\d.]+m?s/, /fixture: page[\d.]+m?s/, /fixture: context[\d.]+m?s/, - /browserContext.close[\d.]+m?s/, ]); await expect(