chore: introduce testInfo.testId (#21670)

This commit is contained in:
Pavel Feldman 2023-03-14 15:58:55 -07:00 committed by GitHub
parent 7666894d77
commit 27048adebe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 58 additions and 10 deletions

View File

@ -248,6 +248,12 @@ Optional description that will be reflected in a test report.
Test function as passed to `test(title, testFunction)`.
## property: TestInfo.testId
* since: v1.32
- type: <[string]>
Test id matching the test case id in the reporter API.
## property: TestInfo.line
* since: v1.10
- type: <[int]>

View File

@ -123,14 +123,14 @@ export class Tracing extends SdkObject implements InstrumentationListener, Snaps
if (this._state) {
const o = this._state.options;
if (o.name !== options.name || !o.screenshots !== !options.screenshots || !o.snapshots !== !options.snapshots)
if (!o.screenshots !== !options.screenshots || !o.snapshots !== !options.snapshots)
throw new Error('Tracing has been already started with different options');
return;
}
// TODO: passing the same name for two contexts makes them write into a single file
// and conflict.
const traceName = options.name || createGuid();
// Init the state synchrounously.
// Init the state synchronously.
this._state = { options, traceName, traceFile: '', networkFile: '', tracesDir: '', resourcesDir: '', filesCount: 0, traceSha1s: new Set(), networkSha1s: new Set(), recording: false };
const state = this._state;

View File

@ -17,7 +17,7 @@
import fs from 'fs';
import type EventEmitter from 'events';
import type { ClientSideCallMetadata, StackFrame } from '@protocol/channels';
import type { SerializedClientSideCallMetadata, SerializedStack, SerializedStackFrame } from '@trace/traceUtils';
import type { SerializedClientSideCallMetadata, SerializedStack, SerializedStackFrame } from './isomorphic/traceUtils';
import { yazl, yauzl } from '../zipBundle';
import { ManualPromise } from './manualPromise';
import type { ActionTraceEvent } from '@trace/trace';

View File

@ -5,3 +5,6 @@ common/
[cli.ts]
**
[index.ts]
@testIsomorphic/**

View File

@ -24,6 +24,7 @@ import type { Fixtures, PlaywrightTestArgs, PlaywrightTestOptions, PlaywrightWor
import type { TestInfoImpl } from './worker/testInfo';
import { rootTestType } from './common/testType';
import { type ContextReuseMode } from './common/types';
import { artifactsFolderName } from './isomorphic/folders';
export { expect } from './matchers/expect';
export { store } from './store';
export const _baseTest: TestType<{}, {}> = rootTestType.test;
@ -79,7 +80,7 @@ const playwrightFixtures: Fixtures<TestFixtures, WorkerFixtures> = ({
let dir: string | undefined;
await use(() => {
if (!dir) {
dir = path.join(workerInfo.project.outputDir, '.playwright-artifacts-' + workerInfo.workerIndex);
dir = path.join(workerInfo.project.outputDir, artifactsFolderName(workerInfo.workerIndex));
fs.mkdirSync(dir, { recursive: true });
}
return dir;
@ -88,7 +89,7 @@ const playwrightFixtures: Fixtures<TestFixtures, WorkerFixtures> = ({
await removeFolders([dir]);
}, { scope: 'worker', _title: 'playwright configuration' } as any],
_browserOptions: [async ({ playwright, headless, channel, launchOptions, connectOptions }, use) => {
_browserOptions: [async ({ playwright, headless, channel, launchOptions, connectOptions, _artifactsDir }, use) => {
const options: LaunchOptions = {
handleSIGINT: false,
timeout: 0,
@ -98,6 +99,7 @@ const playwrightFixtures: Fixtures<TestFixtures, WorkerFixtures> = ({
options.headless = headless;
if (channel !== undefined)
options.channel = channel;
options.tracesDir = path.join(_artifactsDir(), 'traces');
for (const browserType of [playwright.chromium, playwright.firefox, playwright.webkit]) {
(browserType as BrowserTypeImpl)._defaultLaunchOptions = options;
@ -255,6 +257,7 @@ const playwrightFixtures: Fixtures<TestFixtures, WorkerFixtures> = ({
const temporaryScreenshots: string[] = [];
const testInfoImpl = testInfo as TestInfoImpl;
const reusedContexts = new Set<BrowserContext>();
let traceOrdinal = 0;
const createInstrumentationListener = (context?: BrowserContext) => {
return {
@ -287,7 +290,11 @@ const playwrightFixtures: Fixtures<TestFixtures, WorkerFixtures> = ({
if (captureTrace) {
const title = [path.relative(testInfo.project.testDir, testInfo.file) + ':' + testInfo.line, ...testInfo.titlePath.slice(1)].join(' ');
if (!(tracing as any)[kTracingStarted]) {
await tracing.start({ ...traceOptions, title });
const ordinalSuffix = traceOrdinal ? `-${traceOrdinal}` : '';
++traceOrdinal;
const retrySuffix = testInfo.retry ? `-${testInfo.retry}` : '';
const name = `${testInfo.testId}${retrySuffix}${ordinalSuffix}`;
await tracing.start({ ...traceOptions, title, name });
(tracing as any)[kTracingStarted] = true;
} else {
await tracing.startChunk({ title });

View File

@ -0,0 +1,19 @@
/**
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export function artifactsFolderName(workerIndex: number) {
return `.playwright-artifacts-${workerIndex}`;
}

View File

@ -56,6 +56,7 @@ export class TestInfoImpl implements TestInfo {
_lastStepId = 0;
// ------------ TestInfo fields ------------
readonly testId: string;
readonly repeatEachIndex: number;
readonly retry: number;
readonly workerIndex: number;
@ -109,6 +110,7 @@ export class TestInfoImpl implements TestInfo {
onStepEnd: (payload: StepEndPayload) => void,
) {
this._test = test;
this.testId = test.id;
this._onStepBegin = onStepBegin;
this._onStepEnd = onStepEnd;
this._startTime = monotonicTime();

View File

@ -2244,6 +2244,11 @@ export interface TestInfo {
*/
stdout: Array<string|Buffer>;
/**
* Test id matching the test case id in the reporter API.
*/
testId: string;
/**
* Timeout in milliseconds for the currently running test. Zero means no timeout. Learn more about
* [various timeouts](https://playwright.dev/docs/test-timeouts).

View File

@ -1,4 +1,5 @@
[*]
@isomorphic/**
@trace/**
@web/**
ui/

View File

@ -16,7 +16,7 @@
import type * as trace from '@trace/trace';
import type * as traceV3 from './versions/traceV3';
import { parseClientSideCallMetadata } from '@trace/traceUtils';
import { parseClientSideCallMetadata } from '@isomorphic/traceUtils';
import type zip from '@zip.js/zip.js';
// @ts-ignore
import zipImport from '@zip.js/zip.js/dist/zip-no-worker-inflate.min.js';

View File

@ -20,8 +20,8 @@ import '@web/common.css';
import React from 'react';
import { TreeView } from '@web/components/treeView';
import type { TreeState } from '@web/components/treeView';
import { TeleReporterReceiver, TeleSuite } from '../../../playwright-test/src/isomorphic/teleReceiver';
import type { TeleTestCase } from '../../../playwright-test/src/isomorphic/teleReceiver';
import { TeleReporterReceiver, TeleSuite } from '@testIsomorphic/teleReceiver';
import type { TeleTestCase } from '@testIsomorphic/teleReceiver';
import type { FullConfig, Suite, TestCase, TestResult, TestStep, Location } from '../../../playwright-test/types/testReporter';
import { SplitView } from '@web/components/splitView';
import { MultiTraceModel } from './modelUtil';

View File

@ -20,6 +20,7 @@
"@isomorphic/*": ["../playwright-core/src/utils/isomorphic/*"],
"@protocol/*": ["../protocol/src/*"],
"@recorder/*": ["../recorder/src/*"],
"@testIsomorphic/*": ["../playwright-test/src/isomorphic/*"],
"@trace/*": ["../trace/src/*"],
"@web/*": ["../web/src/*"],
// Resolving type dependencies will start processing types in @playwright/test

View File

@ -32,6 +32,7 @@ export default defineConfig({
'@injected': path.resolve(__dirname, '../playwright-core/src/server/injected'),
'@isomorphic': path.resolve(__dirname, '../playwright-core/src/utils/isomorphic'),
'@protocol': path.resolve(__dirname, '../protocol/src'),
'@testIsomorphic': path.resolve(__dirname, '../playwright-test/src/isomorphic'),
'@trace': path.resolve(__dirname, '../trace/src'),
'@web': path.resolve(__dirname, '../web/src'),
},

View File

@ -31,6 +31,7 @@ export default defineConfig({
alias: {
'@isomorphic': path.resolve(__dirname, '../playwright-core/src/utils/isomorphic'),
'@protocol': path.resolve(__dirname, '../protocol/src'),
'@testIsomorphic': path.resolve(__dirname, '../playwright-core/src/utils/testIsomorphic'),
'@trace': path.resolve(__dirname, '../trace/src'),
'@web': path.resolve(__dirname, '../web/src'),
},

View File

@ -17,7 +17,7 @@
import type { Frame, Page } from 'playwright-core';
import { ZipFile } from '../../packages/playwright-core/lib/utils/zipFile';
import type { StackFrame } from '../../packages/protocol/src/channels';
import { parseClientSideCallMetadata } from '../../packages/trace/src/traceUtils';
import { parseClientSideCallMetadata } from '../../packages/playwright-core/lib/utils/isomorphic/traceUtils';
import type { ActionTraceEvent } from '../../packages/trace/src/trace';
export async function attachFrame(page: Page, frameId: string, url: string): Promise<Frame> {

View File

@ -15,6 +15,7 @@
"@isomorphic/*": ["./packages/playwright-core/src/utils/isomorphic/*"],
"@protocol/*": ["./packages/protocol/src/*"],
"@recorder/*": ["./packages/recorder/src/*"],
"@testIsomorphic/*": ["./packages/playwright-test/src/isomorphic/*"],
"@trace/*": ["./packages/trace/src/*"],
"@web/*": ["./packages/web/src/*"],
"playwright-core/lib/*": ["./packages/playwright-core/src/*"],

View File

@ -29,6 +29,7 @@ for (const package of fs.readdirSync(packagesDir))
packages.set(package, packagesDir + '/' + package + '/src/');
packages.set('injected', packagesDir + '/playwright-core/src/server/injected/');
packages.set('isomorphic', packagesDir + '/playwright-core/src/utils/isomorphic/');
packages.set('testIsomorphic', packagesDir + '/playwright-test/src/isomorphic/');
const peerDependencies = ['electron', 'react', 'react-dom', '@zip.js/zip.js'];