mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00
chore: run html reporter tests with merged report (#23626)
This commit is contained in:
parent
400c7cd529
commit
abdfe264fa
@ -125,12 +125,14 @@ export class TeleReporterReceiver {
|
||||
private _tests = new Map<string, TeleTestCase>();
|
||||
private _rootDir!: string;
|
||||
private _clearPreviousResultsWhenTestBegins: boolean = false;
|
||||
private _reuseTestCases: boolean;
|
||||
private _reportConfig: MergeReporterConfig | undefined;
|
||||
|
||||
constructor(pathSeparator: string, reporter: Reporter, reportConfig?: MergeReporterConfig) {
|
||||
constructor(pathSeparator: string, reporter: Reporter, reuseTestCases: boolean, reportConfig?: MergeReporterConfig) {
|
||||
this._rootSuite = new TeleSuite('', 'root');
|
||||
this._pathSeparator = pathSeparator;
|
||||
this._reporter = reporter;
|
||||
this._reuseTestCases = reuseTestCases;
|
||||
this._reportConfig = reportConfig;
|
||||
}
|
||||
|
||||
@ -246,7 +248,7 @@ export class TeleReporterReceiver {
|
||||
location: this._absoluteLocation(payload.location),
|
||||
parent: parentStep,
|
||||
startTime: new Date(payload.startTime),
|
||||
duration: 0,
|
||||
duration: -1,
|
||||
steps: [],
|
||||
};
|
||||
if (parentStep)
|
||||
@ -350,7 +352,7 @@ export class TeleReporterReceiver {
|
||||
|
||||
private _mergeTestsInto(jsonTests: JsonTestCase[], parent: TeleSuite) {
|
||||
for (const jsonTest of jsonTests) {
|
||||
let targetTest = parent.tests.find(s => s.title === jsonTest.title);
|
||||
let targetTest = this._reuseTestCases ? parent.tests.find(s => s.title === jsonTest.title) : undefined;
|
||||
if (!targetTest) {
|
||||
targetTest = new TeleTestCase(jsonTest.testId, jsonTest.title, this._absoluteLocation(jsonTest.location));
|
||||
targetTest.parent = parent;
|
||||
|
@ -33,7 +33,7 @@ export async function createMergedReport(config: FullConfigInternal, dir: string
|
||||
patchAttachmentPaths(events, dir);
|
||||
|
||||
const reporters = await createReporters(config, 'merge', reporterDescriptions);
|
||||
const receiver = new TeleReporterReceiver(path.sep, new Multiplexer(reporters), config.config);
|
||||
const receiver = new TeleReporterReceiver(path.sep, new Multiplexer(reporters), false, config.config);
|
||||
|
||||
for (const event of events)
|
||||
await receiver.dispatch(event);
|
||||
|
@ -26,11 +26,11 @@ import { serializeRegexPatterns } from '../isomorphic/teleReceiver';
|
||||
export class TeleReporterEmitter implements Reporter {
|
||||
private _messageSink: (message: JsonEvent) => void;
|
||||
private _rootDir!: string;
|
||||
private _receiverIsInBrowser: boolean;
|
||||
private _skipBuffers: boolean;
|
||||
|
||||
constructor(messageSink: (message: JsonEvent) => void, receiverIsInBrowser: boolean) {
|
||||
constructor(messageSink: (message: JsonEvent) => void, skipBuffers: boolean) {
|
||||
this._messageSink = messageSink;
|
||||
this._receiverIsInBrowser = receiverIsInBrowser;
|
||||
this._skipBuffers = skipBuffers;
|
||||
}
|
||||
|
||||
onBegin(config: FullConfig, suite: Suite) {
|
||||
@ -206,7 +206,7 @@ export class TeleReporterEmitter implements Reporter {
|
||||
return {
|
||||
...a,
|
||||
// There is no Buffer in the browser, so there is no point in sending the data there.
|
||||
base64: (a.body && !this._receiverIsInBrowser) ? a.body.toString('base64') : undefined,
|
||||
base64: (a.body && !this._skipBuffers) ? a.body.toString('base64') : undefined,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ export async function createReporters(config: FullConfigInternal, mode: 'list' |
|
||||
const prints = r.printsToStdio ? r.printsToStdio() : true;
|
||||
return prints;
|
||||
});
|
||||
if (reporters.length && !someReporterPrintsToStdio && mode !== 'merge') {
|
||||
if (reporters.length && !someReporterPrintsToStdio) {
|
||||
// Add a line/dot/list-mode reporter for convenience.
|
||||
// Important to put it first, jsut in case some other reporter stalls onEnd.
|
||||
if (mode === 'list')
|
||||
|
@ -640,7 +640,7 @@ const refreshRootSuite = (eraseResults: boolean): Promise<void> => {
|
||||
loadErrors.push(error);
|
||||
throttleUpdateRootSuite(config, rootSuite, loadErrors, progress);
|
||||
},
|
||||
});
|
||||
}, true);
|
||||
receiver._setClearPreviousResultsWhenTestBegins();
|
||||
return sendMessage('list', {});
|
||||
};
|
||||
|
@ -85,7 +85,44 @@ export async function writeFiles(testInfo: TestInfo, files: Files, initial: bool
|
||||
|
||||
export const cliEntrypoint = path.join(__dirname, '../../packages/playwright-test/cli.js');
|
||||
|
||||
async function runPlaywrightTest(childProcess: CommonFixtures['childProcess'], baseDir: string, params: any, env: NodeJS.ProcessEnv, options: RunOptions): Promise<RunResult> {
|
||||
const mergeReports = async (childProcess: CommonFixtures['childProcess'], cwd: string, env: NodeJS.ProcessEnv = {}, reporter: string | undefined, configFile: string | undefined) => {
|
||||
const command = ['node', cliEntrypoint, 'merge-reports'];
|
||||
if (reporter)
|
||||
command.push('--reporter', reporter);
|
||||
if (configFile)
|
||||
command.push('--config', configFile);
|
||||
command.push('blob-report');
|
||||
const testProcess = childProcess({
|
||||
command,
|
||||
env: cleanEnv({
|
||||
PW_TEST_DEBUG_REPORTERS: '1',
|
||||
PW_TEST_DEBUG_REPORTERS_PRINT_STEPS: '1',
|
||||
PWTEST_TTY_WIDTH: '80',
|
||||
...env
|
||||
}),
|
||||
cwd,
|
||||
});
|
||||
const { exitCode } = await testProcess.exited;
|
||||
return { exitCode, output: testProcess.output.toString() };
|
||||
};
|
||||
|
||||
const configFile = (baseDir: string, files: Files): string | undefined => {
|
||||
for (const [name, content] of Object.entries(files)) {
|
||||
if (name.includes('playwright.config')) {
|
||||
if (content.includes('reporter:'))
|
||||
return path.resolve(baseDir, name);
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
async function runPlaywrightTest(childProcess: CommonFixtures['childProcess'], baseDir: string, params: any, env: NodeJS.ProcessEnv, options: RunOptions, files: Files, useIntermediateMergeReport: boolean): Promise<RunResult> {
|
||||
let reporter;
|
||||
if (useIntermediateMergeReport) {
|
||||
reporter = params.reporter;
|
||||
params.reporter = 'blob';
|
||||
}
|
||||
|
||||
const paramList: string[] = [];
|
||||
for (const key of Object.keys(params)) {
|
||||
for (const value of Array.isArray(params[key]) ? params[key] : [params[key]]) {
|
||||
@ -110,6 +147,12 @@ async function runPlaywrightTest(childProcess: CommonFixtures['childProcess'], b
|
||||
...env,
|
||||
}, options.sendSIGINTAfter);
|
||||
|
||||
if (useIntermediateMergeReport) {
|
||||
const mergeResult = await mergeReports(childProcess, cwd, env, reporter, configFile(baseDir, files));
|
||||
expect(mergeResult.exitCode).toBe(0);
|
||||
output = mergeResult.output;
|
||||
}
|
||||
|
||||
const summary = (re: RegExp) => {
|
||||
let result = 0;
|
||||
let match = re.exec(output);
|
||||
@ -247,6 +290,7 @@ type Fixtures = {
|
||||
runListFiles: (files: Files) => Promise<{ output: string, exitCode: number }>;
|
||||
runWatchTest: (files: Files, env?: NodeJS.ProcessEnv, options?: RunOptions) => Promise<TestChildProcess>;
|
||||
runTSC: (files: Files) => Promise<TSCResult>;
|
||||
useIntermediateMergeReport: boolean;
|
||||
nodeVersion: { major: number, minor: number, patch: number };
|
||||
};
|
||||
|
||||
@ -265,11 +309,11 @@ export const test = base
|
||||
});
|
||||
},
|
||||
|
||||
runInlineTest: async ({ childProcess }, use, testInfo: TestInfo) => {
|
||||
runInlineTest: async ({ childProcess, useIntermediateMergeReport }, use, testInfo: TestInfo) => {
|
||||
const cacheDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'playwright-test-cache-'));
|
||||
await use(async (files: Files, params: Params = {}, env: NodeJS.ProcessEnv = {}, options: RunOptions = {}) => {
|
||||
const baseDir = await writeFiles(testInfo, files, true);
|
||||
return await runPlaywrightTest(childProcess, baseDir, params, { ...env, PWTEST_CACHE_DIR: cacheDir }, options);
|
||||
return await runPlaywrightTest(childProcess, baseDir, params, { ...env, PWTEST_CACHE_DIR: cacheDir }, options, files, useIntermediateMergeReport);
|
||||
});
|
||||
await removeFolderAsync(cacheDir);
|
||||
},
|
||||
@ -314,6 +358,10 @@ export const test = base
|
||||
const [major, minor, patch] = process.versions.node.split('.');
|
||||
await use({ major: +major, minor: +minor, patch: +patch });
|
||||
},
|
||||
|
||||
useIntermediateMergeReport: async ({}, use) => {
|
||||
await use(process.env.PWTEST_INTERMEDIATE_BLOB_REPORT === '1');
|
||||
},
|
||||
});
|
||||
|
||||
const TSCONFIG = {
|
||||
|
@ -64,6 +64,8 @@ test.slow(!!process.env.CI);
|
||||
// Slow tests are 90s.
|
||||
const expect = baseExpect.configure({ timeout: process.env.CI ? 75000 : 25000 });
|
||||
|
||||
test.describe.configure({ mode: 'parallel' });
|
||||
|
||||
const echoReporterJs = `
|
||||
class EchoReporter {
|
||||
onBegin(config, suite) {
|
||||
|
@ -42,7 +42,11 @@ const expect = baseExpect.configure({ timeout: process.env.CI ? 75000 : 25000 })
|
||||
|
||||
test.describe.configure({ mode: 'parallel' });
|
||||
|
||||
test('should generate report', async ({ runInlineTest, showReport, page }) => {
|
||||
for (const useIntermediateMergeReport of [false, true] as const) {
|
||||
test.describe(`${useIntermediateMergeReport ? 'merged' : 'created'}`, () => {
|
||||
test.use({ useIntermediateMergeReport });
|
||||
|
||||
test('should generate report', async ({ runInlineTest, showReport, page }) => {
|
||||
await runInlineTest({
|
||||
'playwright.config.ts': `
|
||||
module.exports = { name: 'project-name' };
|
||||
@ -79,10 +83,10 @@ test('should generate report', async ({ runInlineTest, showReport, page }) => {
|
||||
await expect(page.getByTestId('project-name'), 'should contain project name').toContainText('project-name');
|
||||
|
||||
await expect(page.locator('.metadata-view')).not.toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
test('should not throw when attachment is missing', async ({ runInlineTest, page, showReport }, testInfo) => {
|
||||
test('should not throw when attachment is missing', async ({ runInlineTest, page, showReport }, testInfo) => {
|
||||
const result = await runInlineTest({
|
||||
'playwright.config.ts': `
|
||||
module.exports = { preserveOutput: 'failures-only' };
|
||||
@ -102,9 +106,9 @@ test('should not throw when attachment is missing', async ({ runInlineTest, page
|
||||
await showReport();
|
||||
await page.click('text=passes');
|
||||
await expect(page.getByRole('link', { name: 'screenshot' })).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
test('should include image diff', async ({ runInlineTest, page, showReport }) => {
|
||||
test('should include image diff', async ({ runInlineTest, page, showReport }) => {
|
||||
const expected = Buffer.from('iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAYAAACtWK6eAAAAAXNSR0IArs4c6QAAAhVJREFUeJzt07ERwCAQwLCQ/Xd+FuDcQiFN4MZrZuYDjv7bAfAyg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAiEDVPZBYx6ffy+AAAAAElFTkSuQmCC', 'base64');
|
||||
const result = await runInlineTest({
|
||||
'playwright.config.ts': `
|
||||
@ -156,9 +160,9 @@ test('should include image diff', async ({ runInlineTest, page, showReport }) =>
|
||||
await imageDiff.locator('text="Diff"').click();
|
||||
set.add(await imageDiff.locator('img').getAttribute('src'));
|
||||
expect(set.size, 'Should be three images altogether').toBe(3);
|
||||
});
|
||||
});
|
||||
|
||||
test('should include multiple image diffs', async ({ runInlineTest, page, showReport }) => {
|
||||
test('should include multiple image diffs', async ({ runInlineTest, page, showReport }) => {
|
||||
const IMG_WIDTH = 200;
|
||||
const IMG_HEIGHT = 200;
|
||||
const redImage = createImage(IMG_WIDTH, IMG_HEIGHT, 255, 0, 0);
|
||||
@ -197,9 +201,9 @@ test('should include multiple image diffs', async ({ runInlineTest, page, showRe
|
||||
const image = imageDiff.locator('img').first();
|
||||
await expect(image).toHaveAttribute('src', /.*png/);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
test('should include image diffs for same expectation', async ({ runInlineTest, page, showReport }) => {
|
||||
test('should include image diffs for same expectation', async ({ runInlineTest, page, showReport }) => {
|
||||
const expected = Buffer.from('iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAYAAACtWK6eAAAAAXNSR0IArs4c6QAAAhVJREFUeJzt07ERwCAQwLCQ/Xd+FuDcQiFN4MZrZuYDjv7bAfAyg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAiEDVPZBYx6ffy+AAAAAElFTkSuQmCC', 'base64');
|
||||
const result = await runInlineTest({
|
||||
'playwright.config.ts': `
|
||||
@ -230,9 +234,9 @@ test('should include image diffs for same expectation', async ({ runInlineTest,
|
||||
'Image mismatch: expected.png-1',
|
||||
'Image mismatch: expected.png-2',
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
test('should include image diff when screenshot failed to generate due to animation', async ({ runInlineTest, page, showReport }) => {
|
||||
test('should include image diff when screenshot failed to generate due to animation', async ({ runInlineTest, page, showReport }) => {
|
||||
const result = await runInlineTest({
|
||||
'playwright.config.ts': `
|
||||
module.exports = { use: { viewport: { width: 200, height: 200 }} };
|
||||
@ -270,9 +274,9 @@ test('should include image diff when screenshot failed to generate due to animat
|
||||
const diffSrc = await image.getAttribute('src');
|
||||
const set = new Set([previousSrc, actualSrc, diffSrc]);
|
||||
expect(set.size).toBe(3);
|
||||
});
|
||||
});
|
||||
|
||||
test('should not include image diff with non-images', async ({ runInlineTest, page, showReport }) => {
|
||||
test('should not include image diff with non-images', async ({ runInlineTest, page, showReport }) => {
|
||||
const expected = Buffer.from('iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAYAAACtWK6eAAAAAXNSR0IArs4c6QAAAhVJREFUeJzt07ERwCAQwLCQ/Xd+FuDcQiFN4MZrZuYDjv7bAfAyg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAgEg0AwCASDQDAIBINAMAiEDVPZBYx6ffy+AAAAAElFTkSuQmCC', 'base64');
|
||||
const result = await runInlineTest({
|
||||
'playwright.config.ts': `
|
||||
@ -299,9 +303,9 @@ test('should not include image diff with non-images', async ({ runInlineTest, pa
|
||||
await expect(page.locator('img')).toHaveCount(0);
|
||||
await expect(page.locator('a', { hasText: 'expected-actual' })).toBeVisible();
|
||||
await expect(page.locator('a', { hasText: 'expected-expected' })).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
test('should include screenshot on failure', async ({ runInlineTest, page, showReport }) => {
|
||||
test('should include screenshot on failure', async ({ runInlineTest, page, showReport }) => {
|
||||
const result = await runInlineTest({
|
||||
'playwright.config.ts': `
|
||||
module.exports = {
|
||||
@ -328,9 +332,9 @@ test('should include screenshot on failure', async ({ runInlineTest, page, showR
|
||||
await expect(page.locator('img')).toBeVisible();
|
||||
const src = await page.locator('img').getAttribute('src');
|
||||
expect(src).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
test('should use different path if attachments base url option is provided', async ({ runInlineTest, page, showReport }, testInfo) => {
|
||||
test('should use different path if attachments base url option is provided', async ({ runInlineTest, page, showReport }, testInfo) => {
|
||||
const result = await runInlineTest({
|
||||
'playwright.config.ts': `
|
||||
module.exports = {
|
||||
@ -364,9 +368,9 @@ test('should use different path if attachments base url option is provided', asy
|
||||
|
||||
await expect(page.getByRole('link', { name: 'trace' })).toHaveAttribute('href', /(https:\/\/some-url\.com\/)[^/\s]+?\.[^/\s]+/);
|
||||
await expect(page.locator('div').filter({ hasText: /^Tracestrace$/ }).getByRole('link').first()).toHaveAttribute('href', /trace=(https:\/\/some-url\.com\/)[^/\s]+?\.[^/\s]+/);
|
||||
});
|
||||
});
|
||||
|
||||
test('should include stdio', async ({ runInlineTest, page, showReport }) => {
|
||||
test('should include stdio', async ({ runInlineTest, page, showReport }) => {
|
||||
const result = await runInlineTest({
|
||||
'a.test.js': `
|
||||
import { test, expect } from '@playwright/test';
|
||||
@ -387,9 +391,9 @@ test('should include stdio', async ({ runInlineTest, page, showReport }) => {
|
||||
await expect(page.locator('.attachment-body')).toHaveText('First line\nSecond line');
|
||||
await page.locator('text=stderr').click();
|
||||
await expect(page.locator('.attachment-body').nth(1)).toHaveText('Third line');
|
||||
});
|
||||
});
|
||||
|
||||
test('should highlight error', async ({ runInlineTest, page, showReport }) => {
|
||||
test('should highlight error', async ({ runInlineTest, page, showReport }) => {
|
||||
const result = await runInlineTest({
|
||||
'a.test.js': `
|
||||
import { test, expect } from '@playwright/test';
|
||||
@ -404,9 +408,9 @@ test('should highlight error', async ({ runInlineTest, page, showReport }) => {
|
||||
await showReport();
|
||||
await page.click('text=fails');
|
||||
await expect(page.locator('.test-result-error-message span:has-text("received")').nth(1)).toHaveCSS('color', 'rgb(204, 0, 0)');
|
||||
});
|
||||
});
|
||||
|
||||
test('should show trace source', async ({ runInlineTest, page, showReport }) => {
|
||||
test('should show trace source', async ({ runInlineTest, page, showReport }) => {
|
||||
const result = await runInlineTest({
|
||||
'playwright.config.js': `
|
||||
module.exports = { use: { trace: 'on' } };
|
||||
@ -437,9 +441,9 @@ test('should show trace source', async ({ runInlineTest, page, showReport }) =>
|
||||
/a.test.js:[\d]+/,
|
||||
]);
|
||||
await expect(page.getByTestId('stack-trace').locator('.list-view-entry.selected')).toContainText('a.test.js');
|
||||
});
|
||||
});
|
||||
|
||||
test('should show trace title', async ({ runInlineTest, page, showReport }) => {
|
||||
test('should show trace title', async ({ runInlineTest, page, showReport }) => {
|
||||
const result = await runInlineTest({
|
||||
'playwright.config.js': `
|
||||
module.exports = { use: { trace: 'on' } };
|
||||
@ -458,9 +462,9 @@ test('should show trace title', async ({ runInlineTest, page, showReport }) => {
|
||||
await page.click('text=passes');
|
||||
await page.click('img');
|
||||
await expect(page.locator('.workbench .title')).toHaveText('a.test.js:3 › passes');
|
||||
});
|
||||
});
|
||||
|
||||
test('should show multi trace source', async ({ runInlineTest, page, server, showReport }) => {
|
||||
test('should show multi trace source', async ({ runInlineTest, page, server, showReport }) => {
|
||||
const result = await runInlineTest({
|
||||
'playwright.config.js': `
|
||||
module.exports = { use: { trace: 'on' } };
|
||||
@ -492,9 +496,9 @@ test('should show multi trace source', async ({ runInlineTest, page, server, sho
|
||||
await page.click('.action-title >> text=apiRequestContext.get');
|
||||
await page.click('text=Source');
|
||||
await expect(page.locator('.source-line-running')).toContainText('request.get');
|
||||
});
|
||||
});
|
||||
|
||||
test('should warn user when viewing via file:// protocol', async ({ runInlineTest, page, showReport }, testInfo) => {
|
||||
test('should warn user when viewing via file:// protocol', async ({ runInlineTest, page, showReport }, testInfo) => {
|
||||
const result = await runInlineTest({
|
||||
'playwright.config.js': `
|
||||
module.exports = { use: { trace: 'on' } };
|
||||
@ -522,9 +526,9 @@ test('should warn user when viewing via file:// protocol', async ({ runInlineTes
|
||||
await expect(page.locator('dialog')).toBeVisible();
|
||||
await expect(page.locator('dialog')).toContainText('must be loaded over');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('should show failed and timed out steps and hooks', async ({ runInlineTest, page, showReport }) => {
|
||||
test('should show failed and timed out steps and hooks', async ({ runInlineTest, page, showReport }) => {
|
||||
const result = await runInlineTest({
|
||||
'playwright.config.js': `
|
||||
module.exports = { timeout: 3000 };
|
||||
@ -593,9 +597,9 @@ test('should show failed and timed out steps and hooks', async ({ runInlineTest,
|
||||
/afterEach hook/,
|
||||
/afterAll hook/,
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
test('should render annotations', async ({ runInlineTest, page, showReport }) => {
|
||||
test('should render annotations', async ({ runInlineTest, page, showReport }) => {
|
||||
const result = await runInlineTest({
|
||||
'playwright.config.js': `
|
||||
module.exports = { timeout: 1500 };
|
||||
@ -613,9 +617,9 @@ test('should render annotations', async ({ runInlineTest, page, showReport }) =>
|
||||
await showReport();
|
||||
await page.click('text=skipped test');
|
||||
await expect(page.locator('.test-case-annotation')).toHaveText('skip: I am not interested in this test');
|
||||
});
|
||||
});
|
||||
|
||||
test('should render annotations as link if needed', async ({ runInlineTest, page, showReport, server }) => {
|
||||
test('should render annotations as link if needed', async ({ runInlineTest, page, showReport, server }) => {
|
||||
const result = await runInlineTest({
|
||||
'playwright.config.js': `
|
||||
module.exports = { timeout: 1500 };
|
||||
@ -637,9 +641,9 @@ test('should render annotations as link if needed', async ({ runInlineTest, page
|
||||
await page.getByRole('link', { name: server.EMPTY_PAGE }).click();
|
||||
const popup = await popupPromise;
|
||||
expect(popup.url()).toBe(server.EMPTY_PAGE);
|
||||
});
|
||||
});
|
||||
|
||||
test('should render text attachments as text', async ({ runInlineTest, page, showReport }) => {
|
||||
test('should render text attachments as text', async ({ runInlineTest, page, showReport }) => {
|
||||
const result = await runInlineTest({
|
||||
'a.test.js': `
|
||||
import { test, expect } from '@playwright/test';
|
||||
@ -678,9 +682,9 @@ test('should render text attachments as text', async ({ runInlineTest, page, sho
|
||||
await page.getByText('example.json', { exact: true }).click();
|
||||
await page.getByText('example-utf16.txt', { exact: true }).click();
|
||||
await expect(page.locator('.attachment-body')).toHaveText(['foo', '{"foo":1}', 'utf16 encoded']);
|
||||
});
|
||||
});
|
||||
|
||||
test('should use file-browser friendly extensions for buffer attachments based on contentType', async ({ runInlineTest }, testInfo) => {
|
||||
test('should use file-browser friendly extensions for buffer attachments based on contentType', async ({ runInlineTest }, testInfo) => {
|
||||
const result = await runInlineTest({
|
||||
'a.test.js': `
|
||||
import { test, expect } from '@playwright/test';
|
||||
@ -705,9 +709,9 @@ test('should use file-browser friendly extensions for buffer attachments based o
|
||||
'84a516841ba77a5b4648de2cd0dfcb30ea46dbb4.png', // screenshot-that-already-has-an-extension-with-correct-contentType.png
|
||||
'e9d71f5ee7c92d6dc9e92ffdad17b8bd49418f98.ext-with-spaces', // example.ext with spaces
|
||||
]));
|
||||
});
|
||||
});
|
||||
|
||||
test('should strikethrough textual diff', async ({ runInlineTest, showReport, page }) => {
|
||||
test('should strikethrough textual diff', async ({ runInlineTest, showReport, page }) => {
|
||||
const result = await runInlineTest({
|
||||
'helper.ts': `
|
||||
import { test as base } from '@playwright/test';
|
||||
@ -732,9 +736,9 @@ test('should strikethrough textual diff', async ({ runInlineTest, showReport, pa
|
||||
await page.click('text="is a test"');
|
||||
const stricken = await page.locator('css=strike').innerText();
|
||||
expect(stricken).toBe('old');
|
||||
});
|
||||
});
|
||||
|
||||
test('should strikethrough textual diff with commonalities', async ({ runInlineTest, showReport, page }) => {
|
||||
test('should strikethrough textual diff with commonalities', async ({ runInlineTest, showReport, page }) => {
|
||||
const result = await runInlineTest({
|
||||
'helper.ts': `
|
||||
import { test as base } from '@playwright/test';
|
||||
@ -759,9 +763,9 @@ test('should strikethrough textual diff with commonalities', async ({ runInlineT
|
||||
await page.click('text="is a test"');
|
||||
const stricken = await page.locator('css=strike').innerText();
|
||||
expect(stricken).toBe('old');
|
||||
});
|
||||
});
|
||||
|
||||
test('should differentiate repeat-each test cases', async ({ runInlineTest, showReport, page }) => {
|
||||
test('should differentiate repeat-each test cases', async ({ runInlineTest, showReport, page }) => {
|
||||
test.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/10859' });
|
||||
const result = await runInlineTest({
|
||||
'a.spec.js': `
|
||||
@ -782,9 +786,9 @@ test('should differentiate repeat-each test cases', async ({ runInlineTest, show
|
||||
await page.locator('text=sample').nth(1).click();
|
||||
await expect(page.locator('text=Before Hooks')).toBeVisible();
|
||||
await expect(page.locator('text=ouch')).toBeHidden();
|
||||
});
|
||||
});
|
||||
|
||||
test('should group similar / loop steps', async ({ runInlineTest, showReport, page }) => {
|
||||
test('should group similar / loop steps', async ({ runInlineTest, showReport, page }) => {
|
||||
test.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/10098' });
|
||||
const result = await runInlineTest({
|
||||
'a.spec.js': `
|
||||
@ -805,9 +809,9 @@ test('should group similar / loop steps', async ({ runInlineTest, showReport, pa
|
||||
/expect\.toBe.*10/,
|
||||
/expect\.toEqual.*20/,
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
test('open tests from required file', async ({ runInlineTest, showReport, page }) => {
|
||||
test('open tests from required file', async ({ runInlineTest, showReport, page }) => {
|
||||
test.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/11742' });
|
||||
const result = await runInlineTest({
|
||||
'inner.js': `
|
||||
@ -823,9 +827,9 @@ test('open tests from required file', async ({ runInlineTest, showReport, page }
|
||||
await expect(page.locator('.tree-item-title')).toContainText([
|
||||
/expect\.toBe/,
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('gitCommitInfo plugin', () => {
|
||||
test.describe('gitCommitInfo plugin', () => {
|
||||
test('should include metadata', async ({ runInlineTest, writeFiles, showReport, page }) => {
|
||||
const files = {
|
||||
'uncommitted.txt': `uncommitted file`,
|
||||
@ -962,9 +966,10 @@ test.describe('gitCommitInfo plugin', () => {
|
||||
await expect.soft(page.locator('data-test-id=metadata-error')).toBeVisible();
|
||||
await expect.soft(page.locator('data-test-id=metadata-chip')).not.toBeVisible();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('should report clashing folders', async ({ runInlineTest }) => {
|
||||
test('should report clashing folders', async ({ runInlineTest, useIntermediateMergeReport }) => {
|
||||
test.skip(useIntermediateMergeReport);
|
||||
const result = await runInlineTest({
|
||||
'playwright.config.ts': `
|
||||
module.exports = {
|
||||
@ -981,10 +986,11 @@ test('should report clashing folders', async ({ runInlineTest }) => {
|
||||
const output = result.output;
|
||||
expect(output).toContain('Configuration Error');
|
||||
expect(output).toContain('html-report');
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('report location', () => {
|
||||
test('with config should create report relative to config', async ({ runInlineTest }, testInfo) => {
|
||||
test.describe('report location', () => {
|
||||
test('with config should create report relative to config', async ({ runInlineTest, useIntermediateMergeReport }, testInfo) => {
|
||||
test.skip(useIntermediateMergeReport);
|
||||
const result = await runInlineTest({
|
||||
'nested/project/playwright.config.ts': `
|
||||
module.exports = { reporter: [['html', { outputFolder: '../my-report/' }]] };
|
||||
@ -1044,9 +1050,9 @@ test.describe('report location', () => {
|
||||
expect(result.passed).toBe(1);
|
||||
expect(fs.existsSync(testInfo.outputPath('foo', 'bar', 'baz', 'my-report'))).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('labels', () => {
|
||||
test.describe('labels', () => {
|
||||
test('should show labels in the test row', async ({ runInlineTest, showReport, page }) => {
|
||||
const result = await runInlineTest({
|
||||
'playwright.config.js': `
|
||||
@ -1835,9 +1841,9 @@ test.describe('labels', () => {
|
||||
await expect(page.locator('.test-case-title')).toHaveText('Test passed -- @call @call-details @e2e @regression #VQ457');
|
||||
await expect(page.locator('.label')).toHaveText(['firefox', 'call', 'call-details', 'e2e', 'Monitoring', 'regression']);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('should list tests in the right order', async ({ runInlineTest, showReport, page }) => {
|
||||
test('should list tests in the right order', async ({ runInlineTest, showReport, page }) => {
|
||||
await runInlineTest({
|
||||
'main.spec.ts': `
|
||||
import firstTest from './first';
|
||||
@ -1883,9 +1889,9 @@ test('should list tests in the right order', async ({ runInlineTest, showReport,
|
||||
/main › first › passes\d+m?sfirst.ts:12/,
|
||||
/main › second › passes\d+m?ssecond.ts:5/,
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
test('tests should filter by file', async ({ runInlineTest, showReport, page }) => {
|
||||
test('tests should filter by file', async ({ runInlineTest, showReport, page }) => {
|
||||
const result = await runInlineTest({
|
||||
'file-a.test.js': `
|
||||
const { test } = require('@playwright/test');
|
||||
@ -1918,9 +1924,9 @@ test('tests should filter by file', async ({ runInlineTest, showReport, page })
|
||||
await searchInput.fill('file-a:3');
|
||||
await expect(page.getByText('a test 1')).toBeVisible();
|
||||
await expect(page.getByText('a test 2')).not.toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
test('tests should filter by status', async ({ runInlineTest, showReport, page }) => {
|
||||
test('tests should filter by status', async ({ runInlineTest, showReport, page }) => {
|
||||
const result = await runInlineTest({
|
||||
'a.test.js': `
|
||||
const { test, expect } = require('@playwright/test');
|
||||
@ -1941,4 +1947,6 @@ test('tests should filter by status', async ({ runInlineTest, showReport, page }
|
||||
await expect(page.getByText('a.test.js', { exact: true })).toBeVisible();
|
||||
await expect(page.getByText('failed title')).not.toBeVisible();
|
||||
await expect(page.getByText('passes title')).toBeVisible();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user