test: remove magic headers in ttest (#20867)

Instead, explicitly import from '@playwright/test'.
This commit is contained in:
Dmitry Gozman 2023-02-14 19:20:56 -08:00 committed by GitHub
parent 08be39a80e
commit 91da67fab1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
71 changed files with 1681 additions and 1452 deletions

View File

@ -143,7 +143,7 @@ export const commonFixtures: Fixtures<CommonFixtures, CommonWorkerFixtures> = {
if (testInfo.status !== 'passed' && testInfo.status !== 'skipped' && !process.env.PWTEST_DEBUG) { if (testInfo.status !== 'passed' && testInfo.status !== 'skipped' && !process.env.PWTEST_DEBUG) {
for (const process of processes) { for (const process of processes) {
console.log('====== ' + process.params.command.join(' ')); console.log('====== ' + process.params.command.join(' '));
console.log(stripAnsi(process.fullOutput)); console.log(process.fullOutput.replace(/\x1Bc/g, ''));
console.log('========================================='); console.log('=========================================');
} }
} }

View File

@ -19,7 +19,8 @@ import { test, expect } from './playwright-test-fixtures';
test('should access error in fixture', async ({ runInlineTest }) => { test('should access error in fixture', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'test-error-visible-in-env.spec.ts': ` 'test-error-visible-in-env.spec.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
foo: [async ({}, run, testInfo) => { foo: [async ({}, run, testInfo) => {
await run(); await run();
console.log('ERROR[[[' + JSON.stringify(testInfo.error, undefined, 2) + ']]]'); console.log('ERROR[[[' + JSON.stringify(testInfo.error, undefined, 2) + ']]]');
@ -40,7 +41,8 @@ test('should access error in fixture', async ({ runInlineTest }) => {
test('should access annotations in fixture', async ({ runInlineTest }) => { test('should access annotations in fixture', async ({ runInlineTest }) => {
const { exitCode, report } = await runInlineTest({ const { exitCode, report } = await runInlineTest({
'test-data-visible-in-env.spec.ts': ` 'test-data-visible-in-env.spec.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
foo: [async ({}, run, testInfo) => { foo: [async ({}, run, testInfo) => {
await run(); await run();
testInfo.annotations.push({ type: 'myname', description: 'hello' }); testInfo.annotations.push({ type: 'myname', description: 'hello' });
@ -74,7 +76,8 @@ test('should report projectName in result', async ({ runInlineTest }) => {
}; };
`, `,
'test-data-visible-in-env.spec.ts': ` 'test-data-visible-in-env.spec.ts': `
pwt.test('some test', async ({}, testInfo) => { import { test, expect } from '@playwright/test';
test('some test', async ({}, testInfo) => {
}); });
` `
}); });
@ -86,7 +89,8 @@ test('should report projectName in result', async ({ runInlineTest }) => {
test('should access testInfo.attachments in fixture', async ({ runInlineTest }) => { test('should access testInfo.attachments in fixture', async ({ runInlineTest }) => {
const { exitCode, report } = await runInlineTest({ const { exitCode, report } = await runInlineTest({
'test-data-visible-in-env.spec.ts': ` 'test-data-visible-in-env.spec.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
foo: async ({}, run, testInfo) => { foo: async ({}, run, testInfo) => {
await run(); await run();
testInfo.attachments.push({ name: 'foo', body: Buffer.from([1, 2, 3]), contentType: 'application/octet-stream' }); testInfo.attachments.push({ name: 'foo', body: Buffer.from([1, 2, 3]), contentType: 'application/octet-stream' });

View File

@ -19,7 +19,7 @@ import { test, expect } from './playwright-test-fixtures';
test('should succeed', async ({ runInlineTest }) => { test('should succeed', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'one-success.spec.ts': ` 'one-success.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
class Foo { class Foo {
#logger = 2; #logger = 2;
@ -58,7 +58,7 @@ test('should treat enums equally', async ({ runInlineTest }) => {
} }
`, `,
'example.spec.ts': ` 'example.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
import * as components from './component'; import * as components from './component';
import * as regular from './regular'; import * as regular from './regular';

View File

@ -19,7 +19,7 @@ import { test, expect } from './playwright-test-fixtures';
test('should fail', async ({ runInlineTest }) => { test('should fail', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'one-failure.spec.ts': ` 'one-failure.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('fails', () => { test('fails', () => {
expect(1 + 1).toBe(7); expect(1 + 1).toBe(7);
}); });
@ -28,13 +28,13 @@ test('should fail', async ({ runInlineTest }) => {
expect(result.exitCode).toBe(1); expect(result.exitCode).toBe(1);
expect(result.passed).toBe(0); expect(result.passed).toBe(0);
expect(result.failed).toBe(1); expect(result.failed).toBe(1);
expect(result.output).toContain('1) one-failure.spec.ts:6'); expect(result.output).toContain('1) one-failure.spec.ts:3');
}); });
test('should timeout', async ({ runInlineTest }) => { test('should timeout', async ({ runInlineTest }) => {
const { exitCode, passed, failed, output } = await runInlineTest({ const { exitCode, passed, failed, output } = await runInlineTest({
'one-timeout.spec.js': ` 'one-timeout.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('timeout', async () => { test('timeout', async () => {
await new Promise(f => setTimeout(f, 10000)); await new Promise(f => setTimeout(f, 10000));
}); });
@ -48,8 +48,8 @@ test('should timeout', async ({ runInlineTest }) => {
test('should succeed', async ({ runInlineTest }) => { test('should succeed', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'one-success.spec.js': ` 'one-success.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('succeeds', () => { test('succeeds', () => {
expect(1 + 1).toBe(2); expect(1 + 1).toBe(2);
}); });
@ -62,11 +62,11 @@ test('should succeed', async ({ runInlineTest }) => {
test('should report suite errors', async ({ runInlineTest }) => { test('should report suite errors', async ({ runInlineTest }) => {
const { exitCode, failed, output } = await runInlineTest({ const { exitCode, failed, output } = await runInlineTest({
'suite-error.spec.js': ` 'suite-error.spec.ts': `
if (new Error().stack.includes('workerMain')) if (new Error().stack.includes('workerMain'))
throw new Error('Suite error'); throw new Error('Suite error');
const { test } = pwt; import { test, expect } from '@playwright/test';
test('passes',() => { test('passes',() => {
expect(1 + 1).toBe(2); expect(1 + 1).toBe(2);
}); });
@ -79,8 +79,8 @@ test('should report suite errors', async ({ runInlineTest }) => {
test('should respect nested skip', async ({ runInlineTest }) => { test('should respect nested skip', async ({ runInlineTest }) => {
const { exitCode, passed, failed, skipped } = await runInlineTest({ const { exitCode, passed, failed, skipped } = await runInlineTest({
'nested-skip.spec.js': ` 'nested-skip.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.describe('skipped', () => { test.describe('skipped', () => {
test.skip(); test.skip();
test('succeeds',() => { test('succeeds',() => {
@ -98,7 +98,7 @@ test('should respect nested skip', async ({ runInlineTest }) => {
test('should respect excluded tests', async ({ runInlineTest }) => { test('should respect excluded tests', async ({ runInlineTest }) => {
const { exitCode, passed } = await runInlineTest({ const { exitCode, passed } = await runInlineTest({
'excluded.spec.ts': ` 'excluded.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('included test', () => { test('included test', () => {
expect(1 + 1).toBe(2); expect(1 + 1).toBe(2);
}); });
@ -134,7 +134,7 @@ test('should respect excluded tests', async ({ runInlineTest }) => {
test('should respect focused tests', async ({ runInlineTest }) => { test('should respect focused tests', async ({ runInlineTest }) => {
const { exitCode, passed } = await runInlineTest({ const { exitCode, passed } = await runInlineTest({
'focused.spec.ts': ` 'focused.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('included test', () => { test('included test', () => {
expect(1 + 1).toBe(3); expect(1 + 1).toBe(3);
}); });
@ -182,7 +182,7 @@ test('should respect focused tests', async ({ runInlineTest }) => {
test('skip should take priority over fail', async ({ runInlineTest }) => { test('skip should take priority over fail', async ({ runInlineTest }) => {
const { passed, skipped, failed } = await runInlineTest({ const { passed, skipped, failed } = await runInlineTest({
'test.spec.ts': ` 'test.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.describe('failing suite', () => { test.describe('failing suite', () => {
test.fail(); test.fail();
@ -219,13 +219,13 @@ test('should focus test from one project', async ({ runInlineTest }) => {
] }; ] };
`, `,
'a/afile.spec.ts': ` 'a/afile.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('just a test', () => { test('just a test', () => {
expect(1 + 1).toBe(3); expect(1 + 1).toBe(3);
}); });
`, `,
'b/bfile.spec.ts': ` 'b/bfile.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.only('focused test', () => { test.only('focused test', () => {
expect(1 + 1).toBe(2); expect(1 + 1).toBe(2);
}); });
@ -254,30 +254,33 @@ test('should work with default export', async ({ runInlineTest }) => {
test('should work with test wrapper', async ({ runInlineTest }) => { test('should work with test wrapper', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'helper.js': ` 'helper.js': `
const { test, expect } = require('@playwright/test');
console.log('%%helper'); console.log('%%helper');
exports.wrap = (title, fn) => { exports.wrap = (title, fn) => {
pwt.test(title, fn); test(title, fn);
}; };
`, `,
'a.spec.js': ` 'a.spec.ts': `
import { test, expect } from '@playwright/test';
console.log('%%a.spec'); console.log('%%a.spec');
const { wrap } = require('./helper'); const { wrap } = require('./helper');
wrap('test1', () => { wrap('test1', () => {
console.log('%%test1'); console.log('%%test1');
}); });
pwt.test.describe('suite1', () => { test.describe('suite1', () => {
wrap('suite1.test1', () => { wrap('suite1.test1', () => {
console.log('%%suite1.test1'); console.log('%%suite1.test1');
}); });
}); });
`, `,
'b.spec.js': ` 'b.spec.ts': `
import { test, expect } from '@playwright/test';
console.log('%%b.spec'); console.log('%%b.spec');
const { wrap } = require('./helper'); const { wrap } = require('./helper');
wrap('test2', () => { wrap('test2', () => {
console.log('%%test2'); console.log('%%test2');
}); });
pwt.test.describe('suite2', () => { test.describe('suite2', () => {
wrap('suite2.test2', () => { wrap('suite2.test2', () => {
console.log('%%suite2.test2'); console.log('%%suite2.test2');
}); });
@ -302,33 +305,35 @@ test('should work with test wrapper', async ({ runInlineTest }) => {
test('should work with test helper', async ({ runInlineTest }) => { test('should work with test helper', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'helper-a.js': ` 'helper-a.ts': `
import { test, expect } from '@playwright/test';
console.log('%%helper-a'); console.log('%%helper-a');
pwt.test('test1', () => { test('test1', () => {
console.log('%%test1'); console.log('%%test1');
}); });
pwt.test.describe('suite1', () => { test.describe('suite1', () => {
pwt.test('suite1.test1', () => { test('suite1.test1', () => {
console.log('%%suite1.test1'); console.log('%%suite1.test1');
}); });
}); });
`, `,
'a.spec.js': ` 'a.spec.ts': `
console.log('%%a.spec'); console.log('%%a.spec');
require('./helper-a'); require('./helper-a');
`, `,
'helper-b.js': ` 'helper-b.ts': `
import { test, expect } from '@playwright/test';
console.log('%%helper-b'); console.log('%%helper-b');
pwt.test('test1', () => { test('test1', () => {
console.log('%%test2'); console.log('%%test2');
}); });
pwt.test.describe('suite2', () => { test.describe('suite2', () => {
pwt.test('suite2.test2', () => { test('suite2.test2', () => {
console.log('%%suite2.test2'); console.log('%%suite2.test2');
}); });
}); });
`, `,
'b.spec.js': ` 'b.spec.ts': `
console.log('%%b.spec'); console.log('%%b.spec');
require('./helper-b'); require('./helper-b');
`, `,
@ -353,11 +358,12 @@ test('should work with test helper', async ({ runInlineTest }) => {
test('should support describe() without a title', async ({ runInlineTest }) => { test('should support describe() without a title', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.js': ` 'a.spec.ts': `
pwt.test.describe('suite1', () => { import { test, expect } from '@playwright/test';
pwt.test.describe(() => { test.describe('suite1', () => {
pwt.test.describe('suite2', () => { test.describe(() => {
pwt.test('my test', () => {}); test.describe('suite2', () => {
test('my test', () => {});
}); });
}); });
}); });
@ -365,13 +371,13 @@ test('should support describe() without a title', async ({ runInlineTest }) => {
}, { reporter: 'list' }); }, { reporter: 'list' });
expect(result.exitCode).toBe(0); expect(result.exitCode).toBe(0);
expect(result.passed).toBe(1); expect(result.passed).toBe(1);
expect(result.output).toContain('a.spec.js:8:17 suite1 suite2 my test'); expect(result.output).toContain('a.spec.ts:6:17 suite1 suite2 my test');
}); });
test('test.{skip,fixme} should define a skipped test', async ({ runInlineTest }) => { test('test.{skip,fixme} should define a skipped test', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
const logs = []; const logs = [];
test.skip('foo', () => { test.skip('foo', () => {
console.log('%%dontseethis'); console.log('%%dontseethis');
@ -391,7 +397,7 @@ test('test.{skip,fixme} should define a skipped test', async ({ runInlineTest })
test('should report unhandled rejection during worker shutdown', async ({ runInlineTest }) => { test('should report unhandled rejection during worker shutdown', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('unhandled rejection', async () => { test('unhandled rejection', async () => {
new Promise((f, r) => r(new Error('Unhandled'))); new Promise((f, r) => r(new Error('Unhandled')));
}); });
@ -400,13 +406,14 @@ test('should report unhandled rejection during worker shutdown', async ({ runInl
expect(result.exitCode).toBe(1); expect(result.exitCode).toBe(1);
expect(result.passed).toBe(1); expect(result.passed).toBe(1);
expect(result.output).toContain('Error: Unhandled'); expect(result.output).toContain('Error: Unhandled');
expect(result.output).toContain('a.test.ts:7:33'); expect(result.output).toContain('a.test.ts:4:33');
}); });
test('should not reuse worker after unhandled rejection in test.fail', async ({ runInlineTest }) => { test('should not reuse worker after unhandled rejection in test.fail', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
needsCleanup: async ({}, use) => { needsCleanup: async ({}, use) => {
await use(); await use();
await new Promise(f => setTimeout(f, 3000)); await new Promise(f => setTimeout(f, 3000));
@ -432,7 +439,7 @@ test('should not reuse worker after unhandled rejection in test.fail', async ({
test('should allow unhandled expects in test.fail', async ({ runInlineTest }) => { test('should allow unhandled expects in test.fail', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('failing1', async ({}) => { test('failing1', async ({}) => {
test.fail(); test.fail();
Promise.resolve().then(() => expect(1).toBe(2)); Promise.resolve().then(() => expect(1).toBe(2));
@ -447,8 +454,8 @@ test('should allow unhandled expects in test.fail', async ({ runInlineTest }) =>
test('should support describe.skip', async ({ runInlineTest }) => { test('should support describe.skip', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'nested-skip.spec.js': ` 'nested-skip.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.describe.skip('skipped', () => { test.describe.skip('skipped', () => {
test.describe('nested', () => { test.describe('nested', () => {
test('test1', () => {}); test('test1', () => {});
@ -473,8 +480,8 @@ test('should support describe.skip', async ({ runInlineTest }) => {
test('should support describe.fixme', async ({ runInlineTest }) => { test('should support describe.fixme', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'nested-skip.spec.js': ` 'nested-skip.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.describe.fixme('skipped', () => { test.describe.fixme('skipped', () => {
test.describe('nested', () => { test.describe('nested', () => {
test('test1', () => {}); test('test1', () => {});

View File

@ -18,8 +18,14 @@ import { test, expect } from './playwright-test-fixtures';
test('should filter by file name', async ({ runInlineTest }) => { test('should filter by file name', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': `pwt.test('fails', () => { expect(1).toBe(2); });`, 'a.spec.ts': `
'b.spec.ts': `pwt.test('fails', () => { expect(1).toBe(2); });`, import { test, expect } from '@playwright/test';
test('fails', () => { expect(1).toBe(2); });
`,
'b.spec.ts': `
import { test, expect } from '@playwright/test';
test('fails', () => { expect(1).toBe(2); });
`,
}, undefined, undefined, { additionalArgs: ['a.spec.ts'] }); }, undefined, undefined, { additionalArgs: ['a.spec.ts'] });
expect(result.exitCode).toBe(1); expect(result.exitCode).toBe(1);
expect(result.failed).toBe(1); expect(result.failed).toBe(1);
@ -28,10 +34,22 @@ test('should filter by file name', async ({ runInlineTest }) => {
test('should filter by folder', async ({ runInlineTest }) => { test('should filter by folder', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'foo/x.spec.ts': `pwt.test('fails', () => { expect(1).toBe(2); });`, 'foo/x.spec.ts': `
'foo/y.spec.ts': `pwt.test('fails', () => { expect(1).toBe(2); });`, import { test, expect } from '@playwright/test';
'bar/x.spec.ts': `pwt.test('fails', () => { expect(1).toBe(2); });`, test('fails', () => { expect(1).toBe(2); });
'bar/y.spec.ts': `pwt.test('fails', () => { expect(1).toBe(2); });`, `,
'foo/y.spec.ts': `
import { test, expect } from '@playwright/test';
test('fails', () => { expect(1).toBe(2); });
`,
'bar/x.spec.ts': `
import { test, expect } from '@playwright/test';
test('fails', () => { expect(1).toBe(2); });
`,
'bar/y.spec.ts': `
import { test, expect } from '@playwright/test';
test('fails', () => { expect(1).toBe(2); });
`,
}, undefined, undefined, { additionalArgs: ['bar'] }); }, undefined, undefined, { additionalArgs: ['bar'] });
expect(result.exitCode).toBe(1); expect(result.exitCode).toBe(1);
expect(result.failed).toBe(2); expect(result.failed).toBe(2);
@ -42,12 +60,16 @@ test('should filter by folder', async ({ runInlineTest }) => {
test('should filter by line', async ({ runInlineTest }) => { test('should filter by line', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'foo/x.spec.ts': ` 'foo/x.spec.ts': `
pwt.test('one', () => { expect(1).toBe(2); }); import { test, expect } from '@playwright/test';
pwt.test('two', () => { expect(1).toBe(2); }); test('one', () => { expect(1).toBe(2); });
pwt.test('three', () => { expect(1).toBe(2); }); test('two', () => { expect(1).toBe(2); });
test('three', () => { expect(1).toBe(2); });
`, `,
'foo/y.spec.ts': `pwt.test('fails', () => { expect(1).toBe(2); });`, 'foo/y.spec.ts': `
}, undefined, undefined, { additionalArgs: ['x.spec.ts:6'] }); import { test, expect } from '@playwright/test';
test('fails', () => { expect(1).toBe(2); });
`,
}, undefined, undefined, { additionalArgs: ['x.spec.ts:4'] });
expect(result.exitCode).toBe(1); expect(result.exitCode).toBe(1);
expect(result.failed).toBe(1); expect(result.failed).toBe(1);
expect(result.output).toMatch(/x\.spec\.ts.*two/); expect(result.output).toMatch(/x\.spec\.ts.*two/);
@ -55,14 +77,15 @@ test('should filter by line', async ({ runInlineTest }) => {
test('should filter by line and column', async ({ runInlineTest }) => { test('should filter by line and column', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'foo/x.spec.js': ` 'foo/x.spec.ts': `
pwt.test('yes-full-match', () => { expect(1).toBe(1); }); import { test, expect } from '@playwright/test';
pwt.test('no-wrong-column', () => { expect(1).toBe(2); }); test('yes-full-match', () => { expect(1).toBe(1); });
pwt.test('yes-no-column-specified', () => { expect(1).toBe(1); }); test('no-wrong-column', () => { expect(1).toBe(2); });
pwt.test('no-match', () => { expect(1).toBe(1); }); test('yes-no-column-specified', () => { expect(1).toBe(1); });
pwt.test('yes-full-match-with-dirname', () => { expect(1).toBe(1); }); test('no-match', () => { expect(1).toBe(1); });
test('yes-full-match-with-dirname', () => { expect(1).toBe(1); });
`, `,
}, undefined, undefined, { additionalArgs: ['x.spec.js:5:11', 'x.spec.js:6:99999', 'x.spec.js:7', 'foo/x.spec.js:9:11'] }); }, undefined, undefined, { additionalArgs: ['x.spec.ts:3:11', 'x.spec.ts:4:99999', 'x.spec.ts:5', 'foo/x.spec.ts:7:11'] });
expect(result.exitCode).toBe(0); expect(result.exitCode).toBe(0);
expect(result.skipped).toBe(0); expect(result.skipped).toBe(0);
expect(result.passed).toBe(3); expect(result.passed).toBe(3);
@ -72,12 +95,16 @@ test('should filter by line and column', async ({ runInlineTest }) => {
test('line should override focused test', async ({ runInlineTest }) => { test('line should override focused test', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'foo/x.spec.ts': ` 'foo/x.spec.ts': `
pwt.test.only('one', () => { expect(1).toBe(2); }); import { test, expect } from '@playwright/test';
pwt.test('two', () => { expect(1).toBe(2); }); test.only('one', () => { expect(1).toBe(2); });
pwt.test.only('three', () => { expect(1).toBe(2); }); test('two', () => { expect(1).toBe(2); });
test.only('three', () => { expect(1).toBe(2); });
`, `,
'foo/y.spec.ts': `pwt.test('fails', () => { expect(1).toBe(2); });`, 'foo/y.spec.ts': `
}, undefined, undefined, { additionalArgs: ['x.spec.ts:6'] }); import { test, expect } from '@playwright/test';
test('fails', () => { expect(1).toBe(2); });
`,
}, undefined, undefined, { additionalArgs: ['x.spec.ts:4'] });
expect(result.exitCode).toBe(1); expect(result.exitCode).toBe(1);
expect(result.failed).toBe(1); expect(result.failed).toBe(1);
expect(result.output).toMatch(/x\.spec\.ts.*two/); expect(result.output).toMatch(/x\.spec\.ts.*two/);
@ -86,12 +113,16 @@ test('line should override focused test', async ({ runInlineTest }) => {
test('should merge filtered line and filtered file', async ({ runInlineTest }) => { test('should merge filtered line and filtered file', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'foo/x.spec.ts': ` 'foo/x.spec.ts': `
pwt.test('one', () => { expect(1).toBe(2); }); import { test, expect } from '@playwright/test';
pwt.test('two', () => { expect(1).toBe(2); }); test('one', () => { expect(1).toBe(2); });
pwt.test('three', () => { expect(1).toBe(2); }); test('two', () => { expect(1).toBe(2); });
test('three', () => { expect(1).toBe(2); });
`, `,
'foo/y.spec.ts': `pwt.test('fails', () => { expect(1).toBe(2); });`, 'foo/y.spec.ts': `
}, undefined, undefined, { additionalArgs: ['x.spec.ts:6', 'x.spec.ts'] }); import { test, expect } from '@playwright/test';
test('fails', () => { expect(1).toBe(2); });
`,
}, undefined, undefined, { additionalArgs: ['x.spec.ts:4', 'x.spec.ts'] });
expect(result.exitCode).toBe(1); expect(result.exitCode).toBe(1);
expect(result.failed).toBe(3); expect(result.failed).toBe(3);
}); });
@ -99,12 +130,16 @@ test('should merge filtered line and filtered file', async ({ runInlineTest }) =
test('should run nothing for missing line', async ({ runInlineTest }) => { test('should run nothing for missing line', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'foo/x.spec.ts': ` 'foo/x.spec.ts': `
pwt.test('one', () => { expect(1).toBe(2); }); import { test, expect } from '@playwright/test';
pwt.test('two', () => { expect(1).toBe(2); }); test('one', () => { expect(1).toBe(2); });
pwt.test('three', () => { expect(1).toBe(2); }); test('two', () => { expect(1).toBe(2); });
test('three', () => { expect(1).toBe(2); });
`, `,
'foo/y.spec.ts': `pwt.test('fails', () => { expect(1).toBe(2); });`, 'foo/y.spec.ts': `
}, undefined, undefined, { additionalArgs: ['x.spec.ts:10', 'y.spec.ts'] }); import { test, expect } from '@playwright/test';
test('fails', () => { expect(1).toBe(2); });
`,
}, undefined, undefined, { additionalArgs: ['x.spec.ts:8', 'y.spec.ts'] });
expect(result.exitCode).toBe(1); expect(result.exitCode).toBe(1);
expect(result.failed).toBe(1); expect(result.failed).toBe(1);
}); });
@ -112,7 +147,7 @@ test('should run nothing for missing line', async ({ runInlineTest }) => {
test('should focus a single nested test spec', async ({ runInlineTest }) => { test('should focus a single nested test spec', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'foo.test.ts': ` 'foo.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass1', ({}) => {}); test('pass1', ({}) => {});
test.describe('suite-1', () => { test.describe('suite-1', () => {
test.describe('suite-2', () => { test.describe('suite-2', () => {
@ -122,17 +157,18 @@ test('should focus a single nested test spec', async ({ runInlineTest }) => {
test('pass3', ({}) => {}); test('pass3', ({}) => {});
`, `,
'bar.test.ts': ` 'bar.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass3', ({}) => {}); test('pass3', ({}) => {});
`, `,
'noooo.test.ts': ` 'noooo.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('no-pass1', ({}) => {}); test('no-pass1', ({}) => {});
`, `,
}, {}, {}, { additionalArgs: ['foo.test.ts:9', 'bar.test.ts'] }); }, {}, {}, { additionalArgs: ['foo.test.ts:6', 'bar.test.ts'] });
expect(result.exitCode).toBe(0); expect(result.exitCode).toBe(0);
expect(result.passed).toBe(2); expect(result.passed).toBe(2);
expect(result.skipped).toBe(0); expect(result.skipped).toBe(0);
console.log(JSON.stringify(result.report, null, 2));
expect(result.report.suites[0].specs[0].title).toEqual('pass3'); expect(result.report.suites[0].specs[0].title).toEqual('pass3');
expect(result.report.suites[1].suites[0].suites[0].specs[0].title).toEqual('pass2'); expect(result.report.suites[1].suites[0].suites[0].specs[0].title).toEqual('pass2');
}); });
@ -140,7 +176,7 @@ test('should focus a single nested test spec', async ({ runInlineTest }) => {
test('should focus a single test suite', async ({ runInlineTest }) => { test('should focus a single test suite', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'foo.test.ts': ` 'foo.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass1', ({}) => {}); test('pass1', ({}) => {});
test.describe('suite-1', () => { test.describe('suite-1', () => {
test.describe('suite-2', () => { test.describe('suite-2', () => {
@ -151,10 +187,10 @@ test('should focus a single test suite', async ({ runInlineTest }) => {
test('pass4', ({}) => {}); test('pass4', ({}) => {});
`, `,
'bar.test.ts': ` 'bar.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('no-pass1', ({}) => {}); test('no-pass1', ({}) => {});
`, `,
}, {}, {}, { additionalArgs: ['foo.test.ts:8'] }); }, {}, {}, { additionalArgs: ['foo.test.ts:5'] });
expect(result.exitCode).toBe(0); expect(result.exitCode).toBe(0);
expect(result.passed).toBe(2); expect(result.passed).toBe(2);
expect(result.skipped).toBe(0); expect(result.skipped).toBe(0);

View File

@ -24,7 +24,7 @@ test('should be able to define config', async ({ runInlineTest }) => {
module.exports = { timeout: 12345 }; module.exports = { timeout: 12345 };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async ({}, testInfo) => { test('pass', async ({}, testInfo) => {
expect(testInfo.timeout).toBe(12345); expect(testInfo.timeout).toBe(12345);
}); });
@ -41,7 +41,7 @@ test('should prioritize project timeout', async ({ runInlineTest }) => {
module.exports = { timeout: 500, projects: [{ timeout: 10000}, {}] }; module.exports = { timeout: 500, projects: [{ timeout: 10000}, {}] };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async ({}, testInfo) => { test('pass', async ({}, testInfo) => {
await new Promise(f => setTimeout(f, 1500)); await new Promise(f => setTimeout(f, 1500));
}); });
@ -60,7 +60,7 @@ test('should prioritize command line timeout over project timeout', async ({ run
module.exports = { projects: [{ timeout: 10000}] }; module.exports = { projects: [{ timeout: 10000}] };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async ({}, testInfo) => { test('pass', async ({}, testInfo) => {
await new Promise(f => setTimeout(f, 1500)); await new Promise(f => setTimeout(f, 1500));
}); });
@ -81,12 +81,12 @@ test('should read config from --config, resolve relative testDir', async ({ runI
}; };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('ignored', async ({}) => { test('ignored', async ({}) => {
}); });
`, `,
'dir/b.test.ts': ` 'dir/b.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('run', async ({}) => { test('run', async ({}) => {
}); });
`, `,
@ -104,12 +104,12 @@ test('should default testDir to the config file', async ({ runInlineTest }) => {
module.exports = {}; module.exports = {};
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('ignored', async ({}) => { test('ignored', async ({}) => {
}); });
`, `,
'dir/b.test.ts': ` 'dir/b.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('run', async ({}) => { test('run', async ({}) => {
}); });
`, `,
@ -133,7 +133,7 @@ test('should be able to set reporters', async ({ runInlineTest }, testInfo) => {
}; };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async () => { test('pass', async () => {
}); });
` `
@ -154,12 +154,12 @@ test('should support different testDirs', async ({ runInlineTest }) => {
] }; ] };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('runs once', async ({}) => { test('runs once', async ({}) => {
}); });
`, `,
'dir/b.test.ts': ` 'dir/b.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('runs twice', async ({}) => { test('runs twice', async ({}) => {
}); });
`, `,
@ -186,13 +186,13 @@ test('should allow root testDir and use it for relative paths', async ({ runInli
}; };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('fails', async ({}, testInfo) => { test('fails', async ({}, testInfo) => {
expect(1 + 1).toBe(3); expect(1 + 1).toBe(3);
}); });
`, `,
'dir/a.test.ts': ` 'dir/a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('fails', async ({}, testInfo) => { test('fails', async ({}, testInfo) => {
expect(1 + 1).toBe(3); expect(1 + 1).toBe(3);
}); });
@ -203,17 +203,18 @@ test('should allow root testDir and use it for relative paths', async ({ runInli
expect(result.passed).toBe(0); expect(result.passed).toBe(0);
expect(result.skipped).toBe(0); expect(result.skipped).toBe(0);
expect(result.failed).toBe(1); expect(result.failed).toBe(1);
expect(result.output).toContain(`1) ${path.join('dir', 'a.test.ts')}:6:7 fails`); expect(result.output).toContain(`1) ${path.join('dir', 'a.test.ts')}:3:11 fails`);
}); });
test('should throw when test() is called in config file', async ({ runInlineTest }) => { test('should throw when test() is called in config file', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'playwright.config.ts': ` 'playwright.config.ts': `
pwt.test('hey', () => {}); import { test, expect } from '@playwright/test';
test('hey', () => {});
module.exports = {}; module.exports = {};
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test', async ({}) => { test('test', async ({}) => {
}); });
`, `,
@ -230,7 +231,7 @@ test('should filter by project, case-insensitive', async ({ runInlineTest }) =>
] }; ] };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async ({}, testInfo) => { test('pass', async ({}, testInfo) => {
console.log(testInfo.project.name); console.log(testInfo.project.name);
}); });
@ -252,7 +253,7 @@ test('should print nice error when project is unknown', async ({ runInlineTest }
] }; ] };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async ({}, testInfo) => { test('pass', async ({}, testInfo) => {
console.log(testInfo.project.name); console.log(testInfo.project.name);
}); });
@ -273,7 +274,7 @@ test('should filter by project list, case-insensitive', async ({ runInlineTest }
] }; ] };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async ({}, testInfo) => { test('pass', async ({}, testInfo) => {
console.log(testInfo.project.name); console.log(testInfo.project.name);
}); });
@ -299,7 +300,7 @@ test('should filter when duplicate project names exist', async ({ runInlineTest
] }; ] };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async ({}, testInfo) => { test('pass', async ({}, testInfo) => {
console.log(testInfo.project.name); console.log(testInfo.project.name);
}); });
@ -322,7 +323,7 @@ test('should print nice error when some of the projects are unknown', async ({ r
] }; ] };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async ({}, testInfo) => { test('pass', async ({}, testInfo) => {
console.log(testInfo.project.name); console.log(testInfo.project.name);
}); });
@ -338,7 +339,7 @@ test('should work without config file', async ({ runInlineTest }) => {
throw new Error('This file should not be required'); throw new Error('This file should not be required');
`, `,
'dir/a.test.ts': ` 'dir/a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async ({}) => { test('pass', async ({}) => {
test.expect(1 + 1).toBe(2); test.expect(1 + 1).toBe(2);
}); });
@ -361,7 +362,8 @@ test('should inherit use options in projects', async ({ runInlineTest }) => {
}; };
`, `,
'a.test.ts': ` 'a.test.ts': `
const test = pwt.test.extend({ foo: ['', {option:true}], bar: ['', {option: true}] }); import { test as base, expect } from '@playwright/test';
const test = base.extend({ foo: ['', {option:true}], bar: ['', {option: true}] });
test('pass', async ({ foo, bar }, testInfo) => { test('pass', async ({ foo, bar }, testInfo) => {
test.expect(foo).toBe('config'); test.expect(foo).toBe('config');
test.expect(bar).toBe('project'); test.expect(bar).toBe('project');
@ -381,7 +383,7 @@ test('should support ignoreSnapshots config option', async ({ runInlineTest }) =
}; };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async ({}, testInfo) => { test('pass', async ({}, testInfo) => {
expect('foo').toMatchSnapshot(); expect('foo').toMatchSnapshot();
expect('foo').not.toMatchSnapshot(); expect('foo').not.toMatchSnapshot();
@ -401,7 +403,7 @@ test('should validate workers option set to percent', async ({ runInlineTest },
}; };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async () => { test('pass', async () => {
}); });
` `
@ -418,7 +420,7 @@ test('should throw when workers option is invalid', async ({ runInlineTest }) =>
}; };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async () => { test('pass', async () => {
}); });
` `
@ -436,7 +438,7 @@ test('should work with undefined values and base', async ({ runInlineTest }) =>
}; };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async ({}, testInfo) => { test('pass', async ({}, testInfo) => {
expect(testInfo.config.updateSnapshots).toBe('missing'); expect(testInfo.config.updateSnapshots).toBe('missing');
}); });

View File

@ -27,7 +27,7 @@ test('should run projects with dependencies', async ({ runInlineTest }) => {
], ],
};`, };`,
'test.spec.ts': ` 'test.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test', async ({}, testInfo) => { test('test', async ({}, testInfo) => {
console.log('\\n%%' + testInfo.project.name); console.log('\\n%%' + testInfo.project.name);
}); });
@ -49,7 +49,7 @@ test('should not run projects with dependencies when --no-deps is passed', async
], ],
};`, };`,
'test.spec.ts': ` 'test.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test', async ({}, testInfo) => { test('test', async ({}, testInfo) => {
console.log('\\n%%' + testInfo.project.name); console.log('\\n%%' + testInfo.project.name);
}); });
@ -71,7 +71,7 @@ test('should not run project if dependency failed', async ({ runInlineTest }) =>
], ],
};`, };`,
'test.spec.ts': ` 'test.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test', async ({}, testInfo) => { test('test', async ({}, testInfo) => {
console.log('\\n%%' + testInfo.project.name); console.log('\\n%%' + testInfo.project.name);
if (testInfo.project.name === 'B') if (testInfo.project.name === 'B')
@ -101,7 +101,7 @@ test('should not run project if dependency failed (2)', async ({ runInlineTest }
], ],
};`, };`,
'test.spec.ts': ` 'test.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test', async ({}, testInfo) => { test('test', async ({}, testInfo) => {
console.log('\\n%%' + testInfo.project.name); console.log('\\n%%' + testInfo.project.name);
if (testInfo.project.name === 'B1') if (testInfo.project.name === 'B1')
@ -124,7 +124,7 @@ test('should filter by project list, but run deps', async ({ runInlineTest }) =>
] }; ] };
`, `,
'test.spec.ts': ` 'test.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async ({}, testInfo) => { test('pass', async ({}, testInfo) => {
console.log('\\n%%' + testInfo.project.name); console.log('\\n%%' + testInfo.project.name);
}); });
@ -145,12 +145,18 @@ test('should not filter dependency by file name', async ({ runInlineTest }) => {
{ name: 'B', dependencies: ['A'] }, { name: 'B', dependencies: ['A'] },
] }; ] };
`, `,
'one.spec.ts': `pwt.test('fails', () => { expect(1).toBe(2); });`, 'one.spec.ts': `
'two.spec.ts': `pwt.test('pass', () => { });`, import { test, expect } from '@playwright/test';
test('fails', () => { expect(1).toBe(2); });
`,
'two.spec.ts': `
import { test, expect } from '@playwright/test';
test('pass', () => { });
`,
}, undefined, undefined, { additionalArgs: ['two.spec.ts'] }); }, undefined, undefined, { additionalArgs: ['two.spec.ts'] });
expect(result.exitCode).toBe(1); expect(result.exitCode).toBe(1);
expect(result.failed).toBe(1); expect(result.failed).toBe(1);
expect(result.output).toContain('1) [A] one.spec.ts:4:5 fails'); expect(result.output).toContain('1) [A] one.spec.ts:3:11 fails');
}); });
test('should not filter dependency by only', async ({ runInlineTest }) => { test('should not filter dependency by only', async ({ runInlineTest }) => {
@ -162,16 +168,20 @@ test('should not filter dependency by only', async ({ runInlineTest }) => {
] }; ] };
`, `,
'setup.ts': ` 'setup.ts': `
pwt.test('passes', () => { import { test, expect } from '@playwright/test';
console.log('\\n%% setup in ' + pwt.test.info().project.name); test('passes', () => {
console.log('\\n%% setup in ' + test.info().project.name);
}); });
pwt.test.only('passes 2', () => { test.only('passes 2', () => {
console.log('\\n%% setup 2 in ' + pwt.test.info().project.name); console.log('\\n%% setup 2 in ' + test.info().project.name);
});
`,
'test.spec.ts': `
import { test, expect } from '@playwright/test';
test('pass', () => {
console.log('\\n%% test in ' + test.info().project.name);
}); });
`, `,
'test.spec.ts': `pwt.test('pass', () => {
console.log('\\n%% test in ' + pwt.test.info().project.name);
});`,
}); });
expect(result.exitCode).toBe(0); expect(result.exitCode).toBe(0);
expect(result.outputLines).toEqual(['setup in setup', 'setup 2 in setup', 'test in browser']); expect(result.outputLines).toEqual(['setup in setup', 'setup 2 in setup', 'test in browser']);
@ -186,16 +196,20 @@ test('should not filter dependency by only 2', async ({ runInlineTest }) => {
] }; ] };
`, `,
'setup.ts': ` 'setup.ts': `
pwt.test('passes', () => { import { test, expect } from '@playwright/test';
console.log('\\n%% setup in ' + pwt.test.info().project.name); test('passes', () => {
console.log('\\n%% setup in ' + test.info().project.name);
}); });
pwt.test.only('passes 2', () => { test.only('passes 2', () => {
console.log('\\n%% setup 2 in ' + pwt.test.info().project.name); console.log('\\n%% setup 2 in ' + test.info().project.name);
});
`,
'test.spec.ts': `
import { test, expect } from '@playwright/test';
test('pass', () => {
console.log('\\n%% test in ' + test.info().project.name);
}); });
`, `,
'test.spec.ts': `pwt.test('pass', () => {
console.log('\\n%% test in ' + pwt.test.info().project.name);
});`,
}, { project: ['setup'] }); }, { project: ['setup'] });
expect(result.exitCode).toBe(0); expect(result.exitCode).toBe(0);
expect(result.outputLines).toEqual(['setup 2 in setup']); expect(result.outputLines).toEqual(['setup 2 in setup']);
@ -210,18 +224,23 @@ test('should not filter dependency by only 3', async ({ runInlineTest }) => {
] }; ] };
`, `,
'setup-1.ts': ` 'setup-1.ts': `
pwt.test('setup 1', () => { import { test, expect } from '@playwright/test';
console.log('\\n%% setup in ' + pwt.test.info().project.name); test('setup 1', () => {
console.log('\\n%% setup in ' + test.info().project.name);
}); });
`, `,
'setup-2.ts': ` 'setup-2.ts': `
pwt.test('setup 2', () => { import { test, expect } from '@playwright/test';
console.log('\\n%% setup 2 in ' + pwt.test.info().project.name); test('setup 2', () => {
console.log('\\n%% setup 2 in ' + test.info().project.name);
});
`,
'test.spec.ts': `
import { test, expect } from '@playwright/test';
test('pass', () => {
console.log('\\n%% test in ' + test.info().project.name);
}); });
`, `,
'test.spec.ts': `pwt.test('pass', () => {
console.log('\\n%% test in ' + pwt.test.info().project.name);
});`,
}, undefined, undefined, { additionalArgs: ['setup-2.ts'] }); }, undefined, undefined, { additionalArgs: ['setup-2.ts'] });
expect(result.exitCode).toBe(0); expect(result.exitCode).toBe(0);
expect(result.outputLines).toEqual(['setup 2 in setup']); expect(result.outputLines).toEqual(['setup 2 in setup']);
@ -236,11 +255,15 @@ test('should report skipped dependent tests', async ({ runInlineTest }) => {
] }; ] };
`, `,
'setup.ts': ` 'setup.ts': `
pwt.test('setup', () => { import { test, expect } from '@playwright/test';
test('setup', () => {
expect(1).toBe(2); expect(1).toBe(2);
}); });
`, `,
'test.spec.ts': `pwt.test('pass', () => {});`, 'test.spec.ts': `
import { test, expect } from '@playwright/test';
test('pass', () => {});
`,
}); });
expect(result.exitCode).toBe(1); expect(result.exitCode).toBe(1);
expect(result.passed).toBe(0); expect(result.passed).toBe(0);
@ -256,7 +279,10 @@ test('should report circular dependencies', async ({ runInlineTest }) => {
{ name: 'B', dependencies: ['A'] }, { name: 'B', dependencies: ['A'] },
] }; ] };
`, `,
'test.spec.ts': `pwt.test('pass', () => {});`, 'test.spec.ts': `
import { test, expect } from '@playwright/test';
test('pass', () => {});
`,
}); });
expect(result.exitCode).toBe(1); expect(result.exitCode).toBe(1);
expect(result.output).toContain('Circular dependency detected between projects.'); expect(result.output).toContain('Circular dependency detected between projects.');
@ -273,19 +299,19 @@ test('should run dependency in each shard', async ({ runInlineTest }) => {
}; };
`, `,
'setup.ts': ` 'setup.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('setup', async ({}) => { test('setup', async ({}) => {
console.log('\\n%%setup'); console.log('\\n%%setup');
}); });
`, `,
'test1.spec.ts': ` 'test1.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test1', async ({}) => { test('test1', async ({}) => {
console.log('\\n%%test1'); console.log('\\n%%test1');
}); });
`, `,
'test2.spec.ts': ` 'test2.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test2', async ({}) => { test('test2', async ({}) => {
console.log('\\n%%test2'); console.log('\\n%%test2');
}); });

View File

@ -19,13 +19,12 @@ import { test, expect } from './playwright-test-fixtures';
test('should load nested as esm when package.json has type module', async ({ runInlineTest }) => { test('should load nested as esm when package.json has type module', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'playwright.config.js': ` 'playwright.config.js': `
//@no-header
import * as fs from 'fs'; import * as fs from 'fs';
export default { projects: [{name: 'foo'}] }; export default { projects: [{name: 'foo'}] };
`, `,
'package.json': JSON.stringify({ type: 'module' }), 'package.json': JSON.stringify({ type: 'module' }),
'nested/folder/a.esm.test.js': ` 'nested/folder/a.esm.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('check project name', ({}, testInfo) => { test('check project name', ({}, testInfo) => {
expect(testInfo.project.name).toBe('foo'); expect(testInfo.project.name).toBe('foo');
}); });
@ -46,7 +45,7 @@ test('should support import assertions', async ({ runInlineTest, nodeVersion })
`, `,
'package.json': JSON.stringify({ type: 'module' }), 'package.json': JSON.stringify({ type: 'module' }),
'a.esm.test.ts': ` 'a.esm.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('check project name', ({}, testInfo) => { test('check project name', ({}, testInfo) => {
expect(1).toBe(1); expect(1).toBe(1);
@ -71,7 +70,7 @@ test('should import esm from ts when package.json has type module in experimenta
import { foo } from './b.ts'; import { foo } from './b.ts';
import { bar } from './c.js'; import { bar } from './c.js';
import { qux } from './d.js'; import { qux } from './d.js';
const { test } = pwt; import { test, expect } from '@playwright/test';
test('check project name', ({}, testInfo) => { test('check project name', ({}, testInfo) => {
expect(testInfo.project.name).toBe('foo'); expect(testInfo.project.name).toBe('foo');
expect(bar).toBe('bar'); expect(bar).toBe('bar');
@ -85,7 +84,6 @@ test('should import esm from ts when package.json has type module in experimenta
export const bar: string = 'bar'; export const bar: string = 'bar';
`, `,
'd.js': ` 'd.js': `
//@no-header
export const qux = 'qux'; export const qux = 'qux';
`, `,
}, {}); }, {});
@ -99,7 +97,7 @@ test('should propagate subprocess exit code in experimental mode', async ({ runI
const result = await runInlineTest({ const result = await runInlineTest({
'package.json': JSON.stringify({ type: 'module' }), 'package.json': JSON.stringify({ type: 'module' }),
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('failing test', ({}, testInfo) => { test('failing test', ({}, testInfo) => {
expect(1).toBe(2); expect(1).toBe(2);
}); });
@ -132,7 +130,7 @@ test('should respect path resolver in experimental mode', async ({ runInlineTest
}`, }`,
'a.test.ts': ` 'a.test.ts': `
import { foo } from 'util/b.js'; import { foo } from 'util/b.js';
const { test } = pwt; import { test, expect } from '@playwright/test';
test('check project name', ({}, testInfo) => { test('check project name', ({}, testInfo) => {
expect(testInfo.project.name).toBe(foo); expect(testInfo.project.name).toBe(foo);
}); });
@ -155,7 +153,7 @@ test('should use source maps', async ({ runInlineTest, nodeVersion }) => {
export default { projects: [{name: 'foo'}] }; export default { projects: [{name: 'foo'}] };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('check project name', ({}, testInfo) => { test('check project name', ({}, testInfo) => {
expect(testInfo.project.name).toBe('foo'); expect(testInfo.project.name).toBe('foo');
@ -166,7 +164,7 @@ test('should use source maps', async ({ runInlineTest, nodeVersion }) => {
const output = result.output; const output = result.output;
expect(result.exitCode).toBe(0); expect(result.exitCode).toBe(0);
expect(result.passed).toBe(1); expect(result.passed).toBe(1);
expect(output).toContain('[foo] a.test.ts:7:7 check project name'); expect(output).toContain('[foo] a.test.ts:4:7 check project name');
}); });
test('should show the codeframe in errors', async ({ runInlineTest, nodeVersion }) => { test('should show the codeframe in errors', async ({ runInlineTest, nodeVersion }) => {
@ -178,7 +176,7 @@ test('should show the codeframe in errors', async ({ runInlineTest, nodeVersion
export default { projects: [{name: 'foo'}] }; export default { projects: [{name: 'foo'}] };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('check project name', ({}, testInfo) => { test('check project name', ({}, testInfo) => {
expect(1).toBe(2); expect(1).toBe(2);
@ -200,15 +198,15 @@ test('should show the codeframe in errors', async ({ runInlineTest, nodeVersion
expect(result.failed).toBe(2); expect(result.failed).toBe(2);
expect(output, 'error carrot—via source maps—is positioned appropriately').toContain( expect(output, 'error carrot—via source maps—is positioned appropriately').toContain(
[ [
` > 8 | expect(1).toBe(2);`, ` > 5 | expect(1).toBe(2);`,
` | ^` ` | ^`
].join('\n')); ].join('\n'));
expect(result.output).toContain('FooBarError: my-message'); expect(result.output).toContain('FooBarError: my-message');
expect(result.output).not.toContain('at a.test.ts'); expect(result.output).not.toContain('at a.test.ts');
expect(result.output).toContain(` 12 | test('foobar', async ({}) => {`); expect(result.output).toContain(` 9 | test('foobar', async ({}) => {`);
expect(result.output).toContain(`> 13 | const error = new Error('my-message');`); expect(result.output).toContain(`> 10 | const error = new Error('my-message');`);
expect(result.output).toContain(' | ^'); expect(result.output).toContain(' | ^');
expect(result.output).toContain(' 14 | error.name = \'FooBarError\';'); expect(result.output).toContain(' 11 | error.name = \'FooBarError\';');
}); });
test('should filter by line', async ({ runInlineTest, nodeVersion }) => { test('should filter by line', async ({ runInlineTest, nodeVersion }) => {
@ -221,12 +219,16 @@ test('should filter by line', async ({ runInlineTest, nodeVersion }) => {
export default { projects: [{name: 'foo'}] }; export default { projects: [{name: 'foo'}] };
`, `,
'foo/x.spec.ts': ` 'foo/x.spec.ts': `
pwt.test('one', () => { expect(1).toBe(2); }); import { test, expect } from '@playwright/test';
pwt.test('two', () => { expect(1).toBe(2); }); test('one', () => { expect(1).toBe(2); });
pwt.test('three', () => { expect(1).toBe(2); }); test('two', () => { expect(1).toBe(2); });
test('three', () => { expect(1).toBe(2); });
`, `,
'foo/y.spec.ts': `pwt.test('fails', () => { expect(1).toBe(2); });`, 'foo/y.spec.ts': `
}, undefined, undefined, { additionalArgs: ['x.spec.ts:6'] }); import { test, expect } from '@playwright/test';
test('fails', () => { expect(1).toBe(2); });
`,
}, undefined, undefined, { additionalArgs: ['x.spec.ts:4'] });
expect(result.exitCode).toBe(1); expect(result.exitCode).toBe(1);
expect(result.failed).toBe(1); expect(result.failed).toBe(1);
expect(result.output).toMatch(/x\.spec\.ts.*two/); expect(result.output).toMatch(/x\.spec\.ts.*two/);
@ -238,7 +240,7 @@ test('should resolve .js import to .ts file in ESM mode', async ({ runInlineTest
'package.json': `{ "type": "module" }`, 'package.json': `{ "type": "module" }`,
'playwright.config.ts': `export default { projects: [{name: 'foo'}] };`, 'playwright.config.ts': `export default { projects: [{name: 'foo'}] };`,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
import { gimmeAOne } from './playwright-utils.js'; import { gimmeAOne } from './playwright-utils.js';
test('pass', ({}) => { test('pass', ({}) => {
expect(gimmeAOne()).toBe(1); expect(gimmeAOne()).toBe(1);
@ -260,7 +262,7 @@ test('should resolve .js import to .tsx file in ESM mode', async ({ runInlineTes
'package.json': `{ "type": "module" }`, 'package.json': `{ "type": "module" }`,
'playwright.config.ts': `export default { projects: [{name: 'foo'}] };`, 'playwright.config.ts': `export default { projects: [{name: 'foo'}] };`,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
import { gimmeAOne } from './playwright-utils.js'; import { gimmeAOne } from './playwright-utils.js';
test('pass', ({}) => { test('pass', ({}) => {
expect(gimmeAOne()).toBe(1); expect(gimmeAOne()).toBe(1);
@ -292,7 +294,6 @@ test('should resolve .js import to .tsx file in ESM mode for components', async
`, `,
'src/test.spec.tsx': ` 'src/test.spec.tsx': `
//@no-header
import { test, expect } from '@playwright/experimental-ct-react'; import { test, expect } from '@playwright/experimental-ct-react';
import { Button } from './button.js'; import { Button } from './button.js';
test('pass', async ({ mount }) => { test('pass', async ({ mount }) => {

View File

@ -24,7 +24,7 @@ function monotonicTime(): number {
test('should collect stdio', async ({ runInlineTest }) => { test('should collect stdio', async ({ runInlineTest }) => {
const { exitCode, report } = await runInlineTest({ const { exitCode, report } = await runInlineTest({
'stdio.spec.js': ` 'stdio.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('stdio', () => { test('stdio', () => {
process.stdout.write('stdout text'); process.stdout.write('stdout text');
process.stdout.write(Buffer.from('stdout buffer')); process.stdout.write(Buffer.from('stdout buffer'));
@ -61,7 +61,7 @@ test('should work with typescript', async ({ runInlineTest }) => {
'typescript.spec.ts': ` 'typescript.spec.ts': `
import './global-foo'; import './global-foo';
const { test } = pwt; import { test, expect } from '@playwright/test';
test('should find global foo', () => { test('should find global foo', () => {
expect(global['foo']).toBe(true); expect(global['foo']).toBe(true);
}); });
@ -78,7 +78,7 @@ test('should work with typescript', async ({ runInlineTest }) => {
test('should repeat each', async ({ runInlineTest }) => { test('should repeat each', async ({ runInlineTest }) => {
const { exitCode, report, passed } = await runInlineTest({ const { exitCode, report, passed } = await runInlineTest({
'one-success.spec.js': ` 'one-success.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('succeeds', () => { test('succeeds', () => {
expect(1 + 1).toBe(2); expect(1 + 1).toBe(2);
}); });
@ -94,7 +94,7 @@ test('should repeat each', async ({ runInlineTest }) => {
test('should allow flaky', async ({ runInlineTest }) => { test('should allow flaky', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('flake', async ({}, testInfo) => { test('flake', async ({}, testInfo) => {
expect(testInfo.retry).toBe(1); expect(testInfo.retry).toBe(1);
}); });
@ -107,7 +107,7 @@ test('should allow flaky', async ({ runInlineTest }) => {
test('should fail on unexpected pass', async ({ runInlineTest }) => { test('should fail on unexpected pass', async ({ runInlineTest }) => {
const { exitCode, failed, output } = await runInlineTest({ const { exitCode, failed, output } = await runInlineTest({
'unexpected-pass.spec.js': ` 'unexpected-pass.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('succeeds', () => { test('succeeds', () => {
test.fail(); test.fail();
expect(1 + 1).toBe(2); expect(1 + 1).toBe(2);
@ -123,7 +123,7 @@ test('should respect global timeout', async ({ runInlineTest }) => {
const now = monotonicTime(); const now = monotonicTime();
const { exitCode, output } = await runInlineTest({ const { exitCode, output } = await runInlineTest({
'one-timeout.spec.js': ` 'one-timeout.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('timeout', async () => { test('timeout', async () => {
await new Promise(f => setTimeout(f, 10000)); await new Promise(f => setTimeout(f, 10000));
}); });

View File

@ -19,7 +19,7 @@ import { test, expect } from './playwright-test-fixtures';
test('should poll predicate', async ({ runInlineTest }) => { test('should poll predicate', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('should poll sync predicate', async () => { test('should poll sync predicate', async () => {
let i = 0; let i = 0;
await test.expect.poll(() => ++i).toBe(3); await test.expect.poll(() => ++i).toBe(3);
@ -44,7 +44,7 @@ test('should poll predicate', async ({ runInlineTest }) => {
test('should compile', async ({ runTSC }) => { test('should compile', async ({ runTSC }) => {
const result = await runTSC({ const result = await runTSC({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('should poll sync predicate', async ({ page }) => { test('should poll sync predicate', async ({ page }) => {
let i = 0; let i = 0;
test.expect.poll(() => ++i).toBe(3); test.expect.poll(() => ++i).toBe(3);
@ -71,7 +71,7 @@ test('should compile', async ({ runTSC }) => {
test('should respect timeout', async ({ runInlineTest }) => { test('should respect timeout', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('should fail', async () => { test('should fail', async () => {
await test.expect.poll(() => false, { timeout: 100 }).toBe(3); await test.expect.poll(() => false, { timeout: 100 }).toBe(3);
}); });
@ -81,14 +81,14 @@ test('should respect timeout', async ({ runInlineTest }) => {
expect(result.output).toContain('Timeout 100ms exceeded while waiting on the predicate'); expect(result.output).toContain('Timeout 100ms exceeded while waiting on the predicate');
expect(result.output).toContain('Received: false'); expect(result.output).toContain('Received: false');
expect(result.output).toContain(` expect(result.output).toContain(`
7 | await test.expect.poll(() => false, { timeout: 100 }). 4 | await test.expect.poll(() => false, { timeout: 100 }).
`.trim()); `.trim());
}); });
test('should fail when passed in non-function', async ({ runInlineTest }) => { test('should fail when passed in non-function', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('should fail', async () => { test('should fail', async () => {
await test.expect.poll(false).toBe(3); await test.expect.poll(false).toBe(3);
}); });
@ -101,7 +101,7 @@ test('should fail when passed in non-function', async ({ runInlineTest }) => {
test('should fail when used with web-first assertion', async ({ runInlineTest }) => { test('should fail when used with web-first assertion', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('should fail', async ({ page }) => { test('should fail', async ({ page }) => {
await test.expect.poll(() => page.locator('body')).toHaveText('foo'); await test.expect.poll(() => page.locator('body')).toHaveText('foo');
}); });
@ -114,7 +114,7 @@ test('should fail when used with web-first assertion', async ({ runInlineTest })
test('should time out when running infinite predicate', async ({ runInlineTest }) => { test('should time out when running infinite predicate', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('should fail', async ({ page }) => { test('should fail', async ({ page }) => {
await test.expect.poll(() => new Promise(x => {}), { timeout: 100 }).toBe(42); await test.expect.poll(() => new Promise(x => {}), { timeout: 100 }).toBe(42);
}); });
@ -127,7 +127,7 @@ test('should time out when running infinite predicate', async ({ runInlineTest }
test('should show error that is thrown from predicate', async ({ runInlineTest }) => { test('should show error that is thrown from predicate', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('should fail', async ({ page }) => { test('should fail', async ({ page }) => {
await test.expect.poll(() => { throw new Error('foo bar baz'); }, { timeout: 100 }).toBe(42); await test.expect.poll(() => { throw new Error('foo bar baz'); }, { timeout: 100 }).toBe(42);
}); });
@ -140,7 +140,7 @@ test('should show error that is thrown from predicate', async ({ runInlineTest }
test('should not retry predicate that threw an error', async ({ runInlineTest }) => { test('should not retry predicate that threw an error', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('should fail', async ({ page }) => { test('should fail', async ({ page }) => {
let iteration = 0; let iteration = 0;
await test.expect.poll(() => { await test.expect.poll(() => {
@ -158,7 +158,7 @@ test('should not retry predicate that threw an error', async ({ runInlineTest })
test('should support .not predicate', async ({ runInlineTest }) => { test('should support .not predicate', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('should fail', async ({ page }) => { test('should fail', async ({ page }) => {
let i = 0; let i = 0;
await test.expect.poll(() => ++i).not.toBeLessThan(3); await test.expect.poll(() => ++i).not.toBeLessThan(3);
@ -191,7 +191,7 @@ test('should support custom matchers', async ({ runInlineTest }) => {
}, },
}); });
const { test } = pwt; import { test, expect } from '@playwright/test';
test('should poll', async () => { test('should poll', async () => {
let i = 0; let i = 0;
await test.expect.poll(() => ++i).toBeWithinRange(3, Number.MAX_VALUE); await test.expect.poll(() => ++i).toBeWithinRange(3, Number.MAX_VALUE);
@ -205,7 +205,7 @@ test('should support custom matchers', async ({ runInlineTest }) => {
test('should respect interval', async ({ runInlineTest }) => { test('should respect interval', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('should fail', async () => { test('should fail', async () => {
let probes = 0; let probes = 0;
const startTime = Date.now(); const startTime = Date.now();

View File

@ -19,7 +19,7 @@ import { test, expect } from './playwright-test-fixtures';
test('soft expects should compile', async ({ runTSC }) => { test('soft expects should compile', async ({ runTSC }) => {
const result = await runTSC({ const result = await runTSC({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('should work', () => { test('should work', () => {
test.expect.soft(1+1).toBe(3); test.expect.soft(1+1).toBe(3);
test.expect.soft(1+1, 'custom error message').toBe(3); test.expect.soft(1+1, 'custom error message').toBe(3);
@ -33,7 +33,7 @@ test('soft expects should compile', async ({ runTSC }) => {
test('soft expects should work', async ({ runInlineTest }) => { test('soft expects should work', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('should work', () => { test('should work', () => {
test.expect.soft(1+1).toBe(3); test.expect.soft(1+1).toBe(3);
console.log('woof-woof'); console.log('woof-woof');
@ -47,7 +47,7 @@ test('soft expects should work', async ({ runInlineTest }) => {
test('should report a mixture of soft and non-soft errors', async ({ runInlineTest }) => { test('should report a mixture of soft and non-soft errors', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('should work', ({}) => { test('should work', ({}) => {
test.expect.soft(1+1, 'one plus one').toBe(3); test.expect.soft(1+1, 'one plus one').toBe(3);
test.expect.soft(2*2, 'two times two').toBe(5); test.expect.soft(2*2, 'two times two').toBe(5);
@ -66,7 +66,7 @@ test('should report a mixture of soft and non-soft errors', async ({ runInlineTe
test('testInfo should contain all soft expect errors', async ({ runInlineTest }) => { test('testInfo should contain all soft expect errors', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('should work', ({}, testInfo) => { test('should work', ({}, testInfo) => {
test.expect.soft(1+1, 'one plus one').toBe(3); test.expect.soft(1+1, 'one plus one').toBe(3);
test.expect.soft(2*2, 'two times two').toBe(5); test.expect.soft(2*2, 'two times two').toBe(5);

View File

@ -19,7 +19,7 @@ import { test, expect } from './playwright-test-fixtures';
test('should retry predicate', async ({ runInlineTest }) => { test('should retry predicate', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('should toPass sync predicate', async () => { test('should toPass sync predicate', async () => {
let i = 0; let i = 0;
await test.expect(() => { await test.expect(() => {
@ -51,7 +51,7 @@ test('should retry predicate', async ({ runInlineTest }) => {
test('should respect timeout', async ({ runInlineTest }) => { test('should respect timeout', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('should fail', async () => { test('should fail', async () => {
await test.expect(() => { await test.expect(() => {
expect(1).toBe(2); expect(1).toBe(2);
@ -63,14 +63,14 @@ test('should respect timeout', async ({ runInlineTest }) => {
expect(result.output).toContain('Timeout 100ms exceeded while waiting on the predicate'); expect(result.output).toContain('Timeout 100ms exceeded while waiting on the predicate');
expect(result.output).toContain('Received: 1'); expect(result.output).toContain('Received: 1');
expect(result.output).toContain(` expect(result.output).toContain(`
7 | await test.expect(() => { 4 | await test.expect(() => {
`.trim()); `.trim());
}); });
test('should not fail when used with web-first assertion', async ({ runInlineTest }) => { test('should not fail when used with web-first assertion', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('should fail', async ({ page }) => { test('should fail', async ({ page }) => {
let i = 0; let i = 0;
await test.expect(async () => { await test.expect(async () => {
@ -87,7 +87,7 @@ test('should not fail when used with web-first assertion', async ({ runInlineTes
test('should support .not predicate', async ({ runInlineTest }) => { test('should support .not predicate', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('should pass', async ({ page }) => { test('should pass', async ({ page }) => {
let i = 0; let i = 0;
await test.expect(() => { await test.expect(() => {
@ -104,7 +104,7 @@ test('should support .not predicate', async ({ runInlineTest }) => {
test('should respect interval', async ({ runInlineTest }) => { test('should respect interval', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('should fail', async () => { test('should fail', async () => {
let probes = 0; let probes = 0;
const startTime = Date.now(); const startTime = Date.now();
@ -124,7 +124,7 @@ test('should respect interval', async ({ runInlineTest }) => {
test('should compile', async ({ runTSC }) => { test('should compile', async ({ runTSC }) => {
const result = await runTSC({ const result = await runTSC({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('should poll sync predicate', async ({ page }) => { test('should poll sync predicate', async ({ page }) => {
let i = 0; let i = 0;
test.expect(() => ++i).toPass(); test.expect(() => ++i).toPass();
@ -146,7 +146,7 @@ test('should compile', async ({ runTSC }) => {
test('should use custom message', async ({ runInlineTest }) => { test('should use custom message', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('should fail with custom message', async () => { test('should fail with custom message', async () => {
await test.expect(() => { await test.expect(() => {
expect(1).toBe(3); expect(1).toBe(3);
@ -164,7 +164,7 @@ test('should swallow all soft errors inside toPass matcher, if successful', asyn
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('should respect soft', async () => { test('should respect soft', async () => {
expect.soft('before-toPass').toBe('zzzz'); expect.soft('before-toPass').toBe('zzzz');
let i = 0; let i = 0;
@ -188,7 +188,7 @@ test('should work with no.toPass and failing soft assertion', async ({ runInline
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('should work', async () => { test('should work', async () => {
await test.expect(() => { await test.expect(() => {
expect.soft(1).toBe(2); expect.soft(1).toBe(2);
@ -204,7 +204,7 @@ test('should work with no.toPass and failing soft assertion', async ({ runInline
test('should show only soft errors on last toPass pass', async ({ runInlineTest }) => { test('should show only soft errors on last toPass pass', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('should respect soft', async () => { test('should respect soft', async () => {
let i = 0; let i = 0;
await test.expect(() => { await test.expect(() => {
@ -224,7 +224,7 @@ test('should show only soft errors on last toPass pass', async ({ runInlineTest
test('should work with soft', async ({ runInlineTest }) => { test('should work with soft', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('should respect soft', async () => { test('should respect soft', async () => {
await test.expect.soft(() => { await test.expect.soft(() => {
expect(1).toBe(3); expect(1).toBe(3);
@ -242,7 +242,7 @@ test('should work with soft', async ({ runInlineTest }) => {
test('should not accept TimeoutError', async ({ runInlineTest }) => { test('should not accept TimeoutError', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('should fail', async () => { test('should fail', async () => {
await test.expect(() => {}).not.toPass({ timeout: 1 }); await test.expect(() => {}).not.toPass({ timeout: 1 });
}); });

View File

@ -20,7 +20,8 @@ import { test, expect } from './playwright-test-fixtures';
test('should be able to call expect.extend in config', async ({ runInlineTest }) => { test('should be able to call expect.extend in config', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'helper.ts': ` 'helper.ts': `
pwt.expect.extend({ import { test as base, expect } from '@playwright/test';
expect.extend({
toBeWithinRange(received, floor, ceiling) { toBeWithinRange(received, floor, ceiling) {
const pass = received >= floor && received <= ceiling; const pass = received >= floor && received <= ceiling;
if (pass) { if (pass) {
@ -37,7 +38,7 @@ test('should be able to call expect.extend in config', async ({ runInlineTest })
} }
}, },
}); });
export const test = pwt.test; export const test = base;
`, `,
'expect-test.spec.ts': ` 'expect-test.spec.ts': `
import { test } from './helper'; import { test } from './helper';
@ -54,7 +55,7 @@ test('should be able to call expect.extend in config', async ({ runInlineTest })
test('should not expand huge arrays', async ({ runInlineTest }) => { test('should not expand huge arrays', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'expect-test.spec.ts': ` 'expect-test.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('numeric ranges', () => { test('numeric ranges', () => {
const a1 = Array(100000).fill(1); const a1 = Array(100000).fill(1);
const a2 = Array(100000).fill(1); const a2 = Array(100000).fill(1);
@ -71,7 +72,7 @@ test('should not expand huge arrays', async ({ runInlineTest }) => {
test('should include custom error message', async ({ runInlineTest }) => { test('should include custom error message', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'expect-test.spec.ts': ` 'expect-test.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('custom expect message', () => { test('custom expect message', () => {
test.expect(1+1, 'one plus one is two!').toEqual(3); test.expect(1+1, 'one plus one is two!').toEqual(3);
}); });
@ -90,7 +91,7 @@ test('should include custom error message', async ({ runInlineTest }) => {
test('should include custom error message with web-first assertions', async ({ runInlineTest }) => { test('should include custom error message with web-first assertions', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'expect-test.spec.ts': ` 'expect-test.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('custom expect message', async ({page}) => { test('custom expect message', async ({page}) => {
await expect(page.locator('x-foo'), { message: 'x-foo must be visible' }).toBeVisible({timeout: 1}); await expect(page.locator('x-foo'), { message: 'x-foo must be visible' }).toBeVisible({timeout: 1});
}); });
@ -107,7 +108,7 @@ test('should include custom error message with web-first assertions', async ({ r
test('should work with default expect prototype functions', async ({ runTSC, runInlineTest }) => { test('should work with default expect prototype functions', async ({ runTSC, runInlineTest }) => {
const spec = ` const spec = `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async () => { test('pass', async () => {
const expected = [1, 2, 3, 4, 5, 6]; const expected = [1, 2, 3, 4, 5, 6];
test.expect([4, 1, 6, 7, 3, 5, 2, 5, 4, 6]).toEqual( test.expect([4, 1, 6, 7, 3, 5, 2, 5, 4, 6]).toEqual(
@ -136,6 +137,7 @@ test('should work with default expect prototype functions', async ({ runTSC, run
test('should work with generic matchers', async ({ runTSC }) => { test('should work with generic matchers', async ({ runTSC }) => {
const result = await runTSC({ const result = await runTSC({
'a.spec.ts': ` 'a.spec.ts': `
import { expect } from '@playwright/test';
expect(42).toBe(42); expect(42).toBe(42);
expect(0.1 + 0.2).toBeCloseTo(0.3, 5); expect(0.1 + 0.2).toBeCloseTo(0.3, 5);
expect(null).toBeDefined(); expect(null).toBeDefined();
@ -184,6 +186,7 @@ test('should work with generic matchers', async ({ runTSC }) => {
test('should compile generic matchers', async ({ runTSC }) => { test('should compile generic matchers', async ({ runTSC }) => {
const result = await runTSC({ const result = await runTSC({
'a.spec.ts': ` 'a.spec.ts': `
import { expect } from '@playwright/test';
expect(42).toBe(42); expect(42).toBe(42);
expect(42).toBeCloseTo(42); expect(42).toBeCloseTo(42);
expect(42).toBeCloseTo(42, 5); expect(42).toBeCloseTo(42, 5);
@ -250,7 +253,7 @@ test('should compile generic matchers', async ({ runTSC }) => {
test('should work with expect message', async ({ runTSC }) => { test('should work with expect message', async ({ runTSC }) => {
const result = await runTSC({ const result = await runTSC({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.expect(42, 'this is expect message').toBe(42); test.expect(42, 'this is expect message').toBe(42);
` `
}); });
@ -260,7 +263,7 @@ test('should work with expect message', async ({ runTSC }) => {
test('should work with default expect matchers and esModuleInterop=false', async ({ runTSC }) => { test('should work with default expect matchers and esModuleInterop=false', async ({ runTSC }) => {
const result = await runTSC({ const result = await runTSC({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.expect(42).toBe(42); test.expect(42).toBe(42);
`, `,
'tsconfig.json': JSON.stringify({ 'tsconfig.json': JSON.stringify({
@ -295,7 +298,7 @@ test('should work with custom PlaywrightTest namespace', async ({ runTSC }) => {
} }
`, `,
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.expect.extend({ test.expect.extend({
toBeWithinRange() { }, toBeWithinRange() { },
}); });
@ -315,7 +318,7 @@ test('should work with custom PlaywrightTest namespace', async ({ runTSC }) => {
test('should propose only the relevant matchers when custom expect matcher classes were passed', async ({ runTSC }) => { test('should propose only the relevant matchers when custom expect matcher classes were passed', async ({ runTSC }) => {
const result = await runTSC({ const result = await runTSC({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('custom matchers', async ({ page }) => { test('custom matchers', async ({ page }) => {
await test.expect(page).toHaveURL('https://example.com'); await test.expect(page).toHaveURL('https://example.com');
await test.expect(page).not.toHaveURL('https://example.com'); await test.expect(page).not.toHaveURL('https://example.com');
@ -364,10 +367,11 @@ test('should propose only the relevant matchers when custom expect matcher class
test('should return void/Promise when appropriate', async ({ runTSC }) => { test('should return void/Promise when appropriate', async ({ runTSC }) => {
const result = await runTSC({ const result = await runTSC({
'a.spec.ts': ` 'a.spec.ts': `
import { test, expect } from '@playwright/test';
type AssertType<T, S> = S extends T ? AssertNotAny<S> : false; type AssertType<T, S> = S extends T ? AssertNotAny<S> : false;
type AssertNotAny<S> = {notRealProperty: number} extends S ? false : true; type AssertNotAny<S> = {notRealProperty: number} extends S ? false : true;
pwt.test('example', async ({ page }) => { test('example', async ({ page }) => {
{ {
const value = expect(1).toBe(2); const value = expect(1).toBe(2);
const assertion: AssertType<void, typeof value> = true; const assertion: AssertType<void, typeof value> = true;
@ -407,7 +411,7 @@ test.describe('helpful expect errors', () => {
test('top-level', async ({ runInlineTest }) => { test('top-level', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('explodes', () => { test('explodes', () => {
expect(1).nope(); expect(1).nope();
}); });
@ -420,7 +424,7 @@ test.describe('helpful expect errors', () => {
test('soft', async ({ runInlineTest }) => { test('soft', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('explodes', () => { test('explodes', () => {
expect.soft(1).nope(); expect.soft(1).nope();
}); });
@ -433,7 +437,7 @@ test.describe('helpful expect errors', () => {
test('poll', async ({ runInlineTest }) => { test('poll', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('explodes', () => { test('explodes', () => {
expect.poll(() => {}).nope(); expect.poll(() => {}).nope();
}); });
@ -446,7 +450,7 @@ test.describe('helpful expect errors', () => {
test('not', async ({ runInlineTest }) => { test('not', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('explodes', () => { test('explodes', () => {
expect(1).not.nope(); expect(1).not.nope();
}); });
@ -459,7 +463,7 @@ test.describe('helpful expect errors', () => {
test('bare', async ({ runInlineTest }) => { test('bare', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('explodes', () => { test('explodes', () => {
expect(''); expect('');
}); });
@ -477,7 +481,7 @@ test('should reasonably work in global setup', async ({ runInlineTest }) => {
export default { globalSetup: './global-setup' }; export default { globalSetup: './global-setup' };
`, `,
'global-setup.ts': ` 'global-setup.ts': `
const { expect } = pwt; import { test, expect } from '@playwright/test';
export default async () => { export default async () => {
expect(1).toBe(1); expect(1).toBe(1);
await expect.poll(async () => { await expect.poll(async () => {
@ -488,20 +492,20 @@ test('should reasonably work in global setup', async ({ runInlineTest }) => {
}; };
`, `,
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('skipped', () => {}); test('skipped', () => {});
`, `,
}); });
expect(result.exitCode).toBe(1); expect(result.exitCode).toBe(1);
expect(result.output).toContain('> 11 | expect(1).toBe(2);'); expect(result.output).toContain('> 9 | expect(1).toBe(2);');
}); });
test('should support toHaveURL with baseURL from webServer', async ({ runInlineTest }, testInfo) => { test('should support toHaveURL with baseURL from webServer', async ({ runInlineTest }, testInfo) => {
const port = testInfo.workerIndex + 10500; const port = testInfo.workerIndex + 10500;
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async ({ page }) => { test('pass', async ({ page }) => {
await page.goto('/foobar'); await page.goto('/foobar');
@ -535,7 +539,7 @@ test('should respect expect.timeout', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'playwright.config.js': `module.exports = { expect: { timeout: 1000 } }`, 'playwright.config.js': `module.exports = { expect: { timeout: 1000 } }`,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('timeout', async ({ page }) => { test('timeout', async ({ page }) => {
await page.goto('data:text/html,<div>A</div>'); await page.goto('data:text/html,<div>A</div>');
@ -552,7 +556,7 @@ test('should respect expect.timeout', async ({ runInlineTest }) => {
test('should log scale the time', async ({ runInlineTest }) => { test('should log scale the time', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async ({ page }) => { test('pass', async ({ page }) => {
await page.setContent('<div id=div>Wrong</div>'); await page.setContent('<div id=div>Wrong</div>');
@ -573,7 +577,7 @@ test('should log scale the time', async ({ runInlineTest }) => {
test('should print expected/received before timeout', async ({ runInlineTest }) => { test('should print expected/received before timeout', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('times out waiting for text', async ({ page }) => { test('times out waiting for text', async ({ page }) => {
await page.setContent('<div id=node>Text content</div>'); await page.setContent('<div id=node>Text content</div>');
@ -592,7 +596,7 @@ test('should print expected/received before timeout', async ({ runInlineTest })
test('should print pending operations for toHaveText', async ({ runInlineTest }) => { test('should print pending operations for toHaveText', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('fail', async ({ page }) => { test('fail', async ({ page }) => {
await page.setContent('<div id=node>Text content</div>'); await page.setContent('<div id=node>Text content</div>');
@ -615,7 +619,7 @@ test('should print expected/received on Ctrl+C', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('times out waiting for text', async ({ page }) => { test('times out waiting for text', async ({ page }) => {
await page.setContent('<div id=node>Text content</div>'); await page.setContent('<div id=node>Text content</div>');
@ -636,7 +640,7 @@ test('should print expected/received on Ctrl+C', async ({ runInlineTest }) => {
test('should print timed out error message', async ({ runInlineTest }) => { test('should print timed out error message', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('fail', async ({ page }) => { test('fail', async ({ page }) => {
await page.setContent('<div id=node>Text content</div>'); await page.setContent('<div id=node>Text content</div>');
@ -653,7 +657,7 @@ test('should print timed out error message', async ({ runInlineTest }) => {
test('should not leak long expect message strings', async ({ runInlineTest }) => { test('should not leak long expect message strings', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
let logs: string = 'Ab'; let logs: string = 'Ab';
const consoleLogWatcher = (msg: ConsoleMessage) => { const consoleLogWatcher = (msg: ConsoleMessage) => {

View File

@ -19,7 +19,8 @@ import { test, expect, countTimes } from './playwright-test-fixtures';
test('should handle fixture timeout', async ({ runInlineTest }) => { test('should handle fixture timeout', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
timeout: async ({}, runTest) => { timeout: async ({}, runTest) => {
await runTest(); await runTest();
await new Promise(f => setTimeout(f, 100000)); await new Promise(f => setTimeout(f, 100000));
@ -43,7 +44,8 @@ test('should handle fixture timeout', async ({ runInlineTest }) => {
test('should handle worker fixture timeout', async ({ runInlineTest }) => { test('should handle worker fixture timeout', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
timeout: [async ({}, runTest) => { timeout: [async ({}, runTest) => {
await runTest(); await runTest();
await new Promise(f => setTimeout(f, 100000)); await new Promise(f => setTimeout(f, 100000));
@ -61,7 +63,8 @@ test('should handle worker fixture timeout', async ({ runInlineTest }) => {
test('should handle worker fixture error', async ({ runInlineTest }) => { test('should handle worker fixture error', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
failure: [async ({}, runTest) => { failure: [async ({}, runTest) => {
throw new Error('Worker failed'); throw new Error('Worker failed');
}, { scope: 'worker' }] }, { scope: 'worker' }]
@ -79,7 +82,8 @@ test('should handle worker fixture error', async ({ runInlineTest }) => {
test('should handle worker tear down fixture error', async ({ runInlineTest }) => { test('should handle worker tear down fixture error', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
failure: [async ({}, runTest) => { failure: [async ({}, runTest) => {
await runTest(); await runTest();
throw new Error('Worker failed'); throw new Error('Worker failed');
@ -98,7 +102,8 @@ test('should handle worker tear down fixture error', async ({ runInlineTest }) =
test('should handle worker tear down fixture error after failed test', async ({ runInlineTest }) => { test('should handle worker tear down fixture error after failed test', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
failure: [async ({}, runTest) => { failure: [async ({}, runTest) => {
await runTest(); await runTest();
throw new Error('Worker failed'); throw new Error('Worker failed');
@ -118,7 +123,8 @@ test('should handle worker tear down fixture error after failed test', async ({
test('should throw when using non-defined super worker fixture', async ({ runInlineTest }) => { test('should throw when using non-defined super worker fixture', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
foo: [async ({ foo }, runTest) => { foo: [async ({ foo }, runTest) => {
await runTest(); await runTest();
}, { scope: 'worker' }] }, { scope: 'worker' }]
@ -128,15 +134,16 @@ test('should throw when using non-defined super worker fixture', async ({ runInl
` `
}); });
expect(result.output).toContain(`Fixture "foo" references itself, but does not have a base implementation.`); expect(result.output).toContain(`Fixture "foo" references itself, but does not have a base implementation.`);
expect(result.output).toContain('a.spec.ts:5'); expect(result.output).toContain('a.spec.ts:3');
expect(result.output).toContain('const test = pwt.test.extend'); expect(result.output).toContain('const test = base.extend');
expect(result.exitCode).toBe(1); expect(result.exitCode).toBe(1);
}); });
test('should throw when defining test fixture with the same name as a worker fixture', async ({ runInlineTest }) => { test('should throw when defining test fixture with the same name as a worker fixture', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'e.spec.ts': ` 'e.spec.ts': `
const test1 = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test1 = base.extend({
foo: [async ({}, runTest) => { foo: [async ({}, runTest) => {
await runTest(); await runTest();
}, { scope: 'worker' }] }, { scope: 'worker' }]
@ -150,8 +157,8 @@ test('should throw when defining test fixture with the same name as a worker fix
test2('works', async ({foo}) => {}); test2('works', async ({foo}) => {});
`, `,
}); });
expect(result.output).toContain(`Fixture "foo" has already been registered as a { scope: 'worker' } fixture defined in e.spec.ts:5:30.`); expect(result.output).toContain(`Fixture "foo" has already been registered as a { scope: 'worker' } fixture defined in e.spec.ts:3:26.`);
expect(result.output).toContain(`e.spec.ts:10`); expect(result.output).toContain(`e.spec.ts:8`);
expect(result.output).toContain('const test2 = test1.extend'); expect(result.output).toContain('const test2 = test1.extend');
expect(result.exitCode).toBe(1); expect(result.exitCode).toBe(1);
}); });
@ -159,7 +166,8 @@ test('should throw when defining test fixture with the same name as a worker fix
test('should throw when defining worker fixture with the same name as a test fixture', async ({ runInlineTest }) => { test('should throw when defining worker fixture with the same name as a test fixture', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'e.spec.ts': ` 'e.spec.ts': `
const test1 = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test1 = base.extend({
foo: [async ({}, runTest) => { foo: [async ({}, runTest) => {
await runTest(); await runTest();
}, { scope: 'test' }] }, { scope: 'test' }]
@ -173,8 +181,8 @@ test('should throw when defining worker fixture with the same name as a test fix
test2('works', async ({foo}) => {}); test2('works', async ({foo}) => {});
`, `,
}); });
expect(result.output).toContain(`Fixture "foo" has already been registered as a { scope: 'test' } fixture defined in e.spec.ts:5:30.`); expect(result.output).toContain(`Fixture "foo" has already been registered as a { scope: 'test' } fixture defined in e.spec.ts:3:26.`);
expect(result.output).toContain(`e.spec.ts:10`); expect(result.output).toContain(`e.spec.ts:8`);
expect(result.output).toContain('const test2 = test1.extend'); expect(result.output).toContain('const test2 = test1.extend');
expect(result.exitCode).toBe(1); expect(result.exitCode).toBe(1);
}); });
@ -182,7 +190,8 @@ test('should throw when defining worker fixture with the same name as a test fix
test('should throw when worker fixture depends on a test fixture', async ({ runInlineTest }) => { test('should throw when worker fixture depends on a test fixture', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'f.spec.ts': ` 'f.spec.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
foo: [async ({}, runTest) => { foo: [async ({}, runTest) => {
await runTest(); await runTest();
}, { scope: 'test' }], }, { scope: 'test' }],
@ -195,14 +204,15 @@ test('should throw when worker fixture depends on a test fixture', async ({ runI
test('works', async ({bar}) => {}); test('works', async ({bar}) => {});
`, `,
}); });
expect(result.output).toContain('worker fixture "bar" cannot depend on a test fixture "foo" defined in f.spec.ts:5:29.'); expect(result.output).toContain('worker fixture "bar" cannot depend on a test fixture "foo" defined in f.spec.ts:3:25.');
expect(result.exitCode).toBe(1); expect(result.exitCode).toBe(1);
}); });
test('should define the same fixture in two files', async ({ runInlineTest }) => { test('should define the same fixture in two files', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const test1 = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test1 = base.extend({
foo: [async ({}, runTest) => { foo: [async ({}, runTest) => {
await runTest(); await runTest();
}, { scope: 'worker' }] }, { scope: 'worker' }]
@ -211,7 +221,8 @@ test('should define the same fixture in two files', async ({ runInlineTest }) =>
test1('works', async ({foo}) => {}); test1('works', async ({foo}) => {});
`, `,
'b.spec.ts': ` 'b.spec.ts': `
const test2 = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test2 = base.extend({
foo: [async ({}, runTest) => { foo: [async ({}, runTest) => {
await runTest(); await runTest();
}, { scope: 'worker' }] }, { scope: 'worker' }]
@ -227,7 +238,8 @@ test('should define the same fixture in two files', async ({ runInlineTest }) =>
test('should detect fixture dependency cycle', async ({ runInlineTest }) => { test('should detect fixture dependency cycle', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'x.spec.ts': ` 'x.spec.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
good1: async ({}, run) => run(), good1: async ({}, run) => run(),
foo: async ({bar}, run) => run(), foo: async ({bar}, run) => run(),
bar: async ({baz}, run) => run(), bar: async ({baz}, run) => run(),
@ -240,31 +252,33 @@ test('should detect fixture dependency cycle', async ({ runInlineTest }) => {
`, `,
}); });
expect(result.output).toContain('Fixtures "bar" -> "baz" -> "qux" -> "foo" -> "bar" form a dependency cycle:'); expect(result.output).toContain('Fixtures "bar" -> "baz" -> "qux" -> "foo" -> "bar" form a dependency cycle:');
expect(result.output).toContain('x.spec.ts:5:29 -> x.spec.ts:5:29 -> x.spec.ts:5:29 -> x.spec.ts:5:29'); expect(result.output).toContain('x.spec.ts:3:25 -> x.spec.ts:3:25 -> x.spec.ts:3:25 -> x.spec.ts:3:25');
expect(result.exitCode).toBe(1); expect(result.exitCode).toBe(1);
}); });
test('should not reuse fixtures from one file in another one', async ({ runInlineTest }) => { test('should not reuse fixtures from one file in another one', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const test = pwt.test.extend({ foo: ({}, run) => run() }); import { test as base, expect } from '@playwright/test';
const test = base.extend({ foo: ({}, run) => run() });
test('test1', async ({}) => {}); test('test1', async ({}) => {});
`, `,
'b.spec.ts': ` 'b.spec.ts': `
const test = pwt.test; import { test, expect } from '@playwright/test';
test('test1', async ({}) => {}); test('test1', async ({}) => {});
test('test2', async ({foo}) => {}); test('test2', async ({foo}) => {});
`, `,
}); });
expect(result.output).toContain('Test has unknown parameter "foo".'); expect(result.output).toContain('Test has unknown parameter "foo".');
expect(result.output).toContain('b.spec.ts:7'); expect(result.output).toContain('b.spec.ts:4');
expect(result.output).toContain(`test('test2', async ({foo}) => {})`); expect(result.output).toContain(`test('test2', async ({foo}) => {})`);
}); });
test('should throw for cycle in two overrides', async ({ runInlineTest }) => { test('should throw for cycle in two overrides', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const test1 = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test1 = base.extend({
foo: async ({}, run) => await run('foo'), foo: async ({}, run) => await run('foo'),
bar: async ({}, run) => await run('bar'), bar: async ({}, run) => await run('bar'),
}); });
@ -281,13 +295,14 @@ test('should throw for cycle in two overrides', async ({ runInlineTest }) => {
`, `,
}); });
expect(result.output).toContain('Fixtures "bar" -> "foo" -> "bar" form a dependency cycle:'); expect(result.output).toContain('Fixtures "bar" -> "foo" -> "bar" form a dependency cycle:');
expect(result.output).toContain('a.test.js:12:27 -> a.test.js:9:27'); expect(result.output).toContain('a.test.js:10:27 -> a.test.js:7:27');
}); });
test('should throw when overridden worker fixture depends on a test fixture', async ({ runInlineTest }) => { test('should throw when overridden worker fixture depends on a test fixture', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'f.spec.ts': ` 'f.spec.ts': `
const test1 = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test1 = base.extend({
foo: async ({}, run) => await run('foo'), foo: async ({}, run) => await run('foo'),
bar: [ async ({}, run) => await run('bar'), { scope: 'worker' } ], bar: [ async ({}, run) => await run('bar'), { scope: 'worker' } ],
}); });
@ -298,15 +313,16 @@ test('should throw when overridden worker fixture depends on a test fixture', as
test2('works', async ({bar}) => {}); test2('works', async ({bar}) => {});
`, `,
}); });
expect(result.output).toContain('worker fixture "bar" cannot depend on a test fixture "foo" defined in f.spec.ts:5:30.'); expect(result.output).toContain('worker fixture "bar" cannot depend on a test fixture "foo" defined in f.spec.ts:3:26.');
expect(result.output).toContain('f.spec.ts:9'); expect(result.output).toContain('f.spec.ts:7');
expect(result.exitCode).toBe(1); expect(result.exitCode).toBe(1);
}); });
test('should throw for unknown fixture parameter', async ({ runInlineTest }) => { test('should throw for unknown fixture parameter', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'f.spec.ts': ` 'f.spec.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
foo: async ({ bar }, run) => await run('foo'), foo: async ({ bar }, run) => await run('foo'),
}); });
@ -314,15 +330,16 @@ test('should throw for unknown fixture parameter', async ({ runInlineTest }) =>
`, `,
}); });
expect(result.output).toContain('Fixture "foo" has unknown parameter "bar".'); expect(result.output).toContain('Fixture "foo" has unknown parameter "bar".');
expect(result.output).toContain('f.spec.ts:5'); expect(result.output).toContain('f.spec.ts:3');
expect(result.output).toContain('const test = pwt.test.extend'); expect(result.output).toContain('const test = base.extend');
expect(result.exitCode).toBe(1); expect(result.exitCode).toBe(1);
}); });
test('should throw when calling runTest twice', async ({ runInlineTest }) => { test('should throw when calling runTest twice', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'f.spec.ts': ` 'f.spec.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
foo: async ({}, run) => { foo: async ({}, run) => {
await run(); await run();
await run(); await run();
@ -339,7 +356,8 @@ test('should throw when calling runTest twice', async ({ runInlineTest }) => {
test('should print nice error message for problematic fixtures', async ({ runInlineTest }) => { test('should print nice error message for problematic fixtures', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'x.spec.ts': ` 'x.spec.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
bad: [ undefined, { get scope() { throw new Error('oh my!') } } ], bad: [ undefined, { get scope() { throw new Error('oh my!') } } ],
}); });
test('works', async ({foo}) => {}); test('works', async ({foo}) => {});
@ -347,13 +365,14 @@ test('should print nice error message for problematic fixtures', async ({ runInl
}); });
expect(result.exitCode).toBe(1); expect(result.exitCode).toBe(1);
expect(result.output).toContain('oh my!'); expect(result.output).toContain('oh my!');
expect(result.output).toContain('x.spec.ts:6:49'); expect(result.output).toContain('x.spec.ts:4:49');
}); });
test('should exit with timeout when fixture causes an exception in the test', async ({ runInlineTest }) => { test('should exit with timeout when fixture causes an exception in the test', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
throwAfterTimeout: async ({}, use) => { throwAfterTimeout: async ({}, use) => {
let callback; let callback;
const promise = new Promise((f, r) => callback = r); const promise = new Promise((f, r) => callback = r);
@ -374,7 +393,8 @@ test('should exit with timeout when fixture causes an exception in the test', as
test('should error for unsupported scope', async ({ runInlineTest }) => { test('should error for unsupported scope', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
failure: [async ({}, use) => { failure: [async ({}, use) => {
await use(); await use();
}, { scope: 'foo' }] }, { scope: 'foo' }]
@ -390,7 +410,8 @@ test('should error for unsupported scope', async ({ runInlineTest }) => {
test('should give enough time for fixture teardown', async ({ runInlineTest }) => { test('should give enough time for fixture teardown', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
fixture: async ({ }, use) => { fixture: async ({ }, use) => {
await use(); await use();
console.log('\\n%%teardown start'); console.log('\\n%%teardown start');
@ -416,7 +437,8 @@ test('should give enough time for fixture teardown', async ({ runInlineTest }) =
test('should not teardown when setup times out', async ({ runInlineTest }) => { test('should not teardown when setup times out', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
fixture: async ({ }, use) => { fixture: async ({ }, use) => {
await new Promise(f => setTimeout(f, 1500)); await new Promise(f => setTimeout(f, 1500));
await use(); await use();
@ -437,7 +459,8 @@ test('should not teardown when setup times out', async ({ runInlineTest }) => {
test('should not report fixture teardown error twice', async ({ runInlineTest }) => { test('should not report fixture teardown error twice', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
fixture: async ({ }, use) => { fixture: async ({ }, use) => {
await use(); await use();
throw new Error('Oh my error'); throw new Error('Oh my error');
@ -457,7 +480,8 @@ test('should not report fixture teardown error twice', async ({ runInlineTest })
test('should not report fixture teardown timeout twice', async ({ runInlineTest }) => { test('should not report fixture teardown timeout twice', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
fixture: async ({ }, use) => { fixture: async ({ }, use) => {
await use(); await use();
await new Promise(() => {}); await new Promise(() => {});
@ -470,7 +494,7 @@ test('should not report fixture teardown timeout twice', async ({ runInlineTest
expect(result.exitCode).toBe(1); expect(result.exitCode).toBe(1);
expect(result.failed).toBe(1); expect(result.failed).toBe(1);
expect(result.output).toContain('Test timeout of 1000ms exceeded while tearing down "fixture".'); expect(result.output).toContain('Test timeout of 1000ms exceeded while tearing down "fixture".');
expect(result.output).not.toContain('pwt.test.extend'); // Should not point to the location. expect(result.output).not.toContain('base.extend'); // Should not point to the location.
// TODO: this should be "not.toContain" actually. // TODO: this should be "not.toContain" actually.
expect(result.output).toContain('Worker teardown timeout of 1000ms exceeded while tearing down "fixture".'); expect(result.output).toContain('Worker teardown timeout of 1000ms exceeded while tearing down "fixture".');
}); });
@ -478,7 +502,8 @@ test('should not report fixture teardown timeout twice', async ({ runInlineTest
test('should handle fixture teardown error after test timeout and continue', async ({ runInlineTest }) => { test('should handle fixture teardown error after test timeout and continue', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
fixture: async ({ }, use) => { fixture: async ({ }, use) => {
await use(); await use();
throw new Error('Oh my error'); throw new Error('Oh my error');
@ -502,7 +527,8 @@ test('should handle fixture teardown error after test timeout and continue', asy
test('should report worker fixture teardown with debug info', async ({ runInlineTest }) => { test('should report worker fixture teardown with debug info', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
fixture: [ async ({ }, use) => { fixture: [ async ({ }, use) => {
await use(); await use();
await new Promise(() => {}); await new Promise(() => {});
@ -518,23 +544,24 @@ test('should report worker fixture teardown with debug info', async ({ runInline
'Worker teardown timeout of 1000ms exceeded while tearing down "fixture".', 'Worker teardown timeout of 1000ms exceeded while tearing down "fixture".',
'', '',
'Failed worker ran 20 tests, last 10 tests were:', 'Failed worker ran 20 tests, last 10 tests were:',
'a.spec.ts:12:9 good10', 'a.spec.ts:10:9 good10',
'a.spec.ts:12:9 good11', 'a.spec.ts:10:9 good11',
'a.spec.ts:12:9 good12', 'a.spec.ts:10:9 good12',
'a.spec.ts:12:9 good13', 'a.spec.ts:10:9 good13',
'a.spec.ts:12:9 good14', 'a.spec.ts:10:9 good14',
'a.spec.ts:12:9 good15', 'a.spec.ts:10:9 good15',
'a.spec.ts:12:9 good16', 'a.spec.ts:10:9 good16',
'a.spec.ts:12:9 good17', 'a.spec.ts:10:9 good17',
'a.spec.ts:12:9 good18', 'a.spec.ts:10:9 good18',
'a.spec.ts:12:9 good19', 'a.spec.ts:10:9 good19',
].join('\n')); ].join('\n'));
}); });
test('should not run user fn when require fixture has failed', async ({ runInlineTest }) => { test('should not run user fn when require fixture has failed', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
foo: [ async ({ }, use) => { foo: [ async ({ }, use) => {
console.log('\\n%%foo'); console.log('\\n%%foo');
throw new Error('A test error!'); throw new Error('A test error!');
@ -586,28 +613,30 @@ test('should not run user fn when require fixture has failed', async ({ runInlin
test('should provide helpful error message when digests do not match', async ({ runInlineTest }) => { test('should provide helpful error message when digests do not match', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'helper.ts': ` 'helper.ts': `
export const test = pwt.test.extend({ import { test as base } from '@playwright/test';
export * from '@playwright/test';
export const test = base.extend({
foo: [ async ({}, use) => use(), { scope: 'worker' } ], foo: [ async ({}, use) => use(), { scope: 'worker' } ],
}); });
test.use({ foo: 'foo' }); test.use({ foo: 'foo' });
`, `,
'a.spec.ts': ` 'a.spec.ts': `
import { test } from './helper'; import { test, expect } from './helper';
test('test-a', ({ foo }) => { test('test-a', ({ foo }) => {
expect(foo).toBe('foo'); expect(foo).toBe('foo');
}); });
`, `,
'b.spec.ts': ` 'b.spec.ts': `
import { test } from './helper'; import { test, expect } from './helper';
test('test-b', ({ foo }) => { test('test-b', ({ foo }) => {
expect(foo).toBe('foo'); expect(foo).toBe('foo');
}); });
`, `,
'c.spec.ts': ` 'c.spec.ts': `
import { test } from './helper'; import { test, expect } from './helper';
test('test-c', ({ foo }) => { test('test-c', ({ foo }) => {
expect(foo).toBe('foo'); expect(foo).toBe('foo');

View File

@ -18,8 +18,9 @@ import { test, expect } from './playwright-test-fixtures';
test('should work', async ({ runInlineTest }) => { test('should work', async ({ runInlineTest }) => {
const { results } = await runInlineTest({ const { results } = await runInlineTest({
'a.test.js': ` 'a.test.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
asdf: async ({}, test) => await test(123), asdf: async ({}, test) => await test(123),
}); });
@ -33,8 +34,9 @@ test('should work', async ({ runInlineTest }) => {
test('should work with a sync test function', async ({ runInlineTest }) => { test('should work with a sync test function', async ({ runInlineTest }) => {
const { results } = await runInlineTest({ const { results } = await runInlineTest({
'a.test.js': ` 'a.test.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
asdf: async ({}, test) => await test(123), asdf: async ({}, test) => await test(123),
}); });
@ -48,8 +50,9 @@ test('should work with a sync test function', async ({ runInlineTest }) => {
test('should work with a sync fixture function', async ({ runInlineTest }) => { test('should work with a sync fixture function', async ({ runInlineTest }) => {
const { results } = await runInlineTest({ const { results } = await runInlineTest({
'a.test.js': ` 'a.test.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
asdf: ({}, use) => { asdf: ({}, use) => {
use(123); use(123);
}, },
@ -65,8 +68,9 @@ test('should work with a sync fixture function', async ({ runInlineTest }) => {
test('should work with a non-arrow function', async ({ runInlineTest }) => { test('should work with a non-arrow function', async ({ runInlineTest }) => {
const { results } = await runInlineTest({ const { results } = await runInlineTest({
'a.test.js': ` 'a.test.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
asdf: async ({}, test) => await test(123), asdf: async ({}, test) => await test(123),
}); });
@ -80,8 +84,9 @@ test('should work with a non-arrow function', async ({ runInlineTest }) => {
test('should work with a named function', async ({ runInlineTest }) => { test('should work with a named function', async ({ runInlineTest }) => {
const { results } = await runInlineTest({ const { results } = await runInlineTest({
'a.test.js': ` 'a.test.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
asdf: async ({}, test) => await test(123), asdf: async ({}, test) => await test(123),
}); });
@ -95,8 +100,9 @@ test('should work with a named function', async ({ runInlineTest }) => {
test('should work with renamed parameters', async ({ runInlineTest }) => { test('should work with renamed parameters', async ({ runInlineTest }) => {
const { results } = await runInlineTest({ const { results } = await runInlineTest({
'a.test.js': ` 'a.test.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
asdf: async ({}, test) => await test(123), asdf: async ({}, test) => await test(123),
}); });
@ -110,8 +116,9 @@ test('should work with renamed parameters', async ({ runInlineTest }) => {
test('should work with destructured object', async ({ runInlineTest }) => { test('should work with destructured object', async ({ runInlineTest }) => {
const { results } = await runInlineTest({ const { results } = await runInlineTest({
'a.test.js': ` 'a.test.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
asdf: async ({}, test) => await test({ foo: 'foo', bar: { x: 'x', y: 'y' }, baz: 'baz' }), asdf: async ({}, test) => await test({ foo: 'foo', bar: { x: 'x', y: 'y' }, baz: 'baz' }),
}); });
@ -129,8 +136,9 @@ test('should work with destructured object', async ({ runInlineTest }) => {
test('should work with destructured array', async ({ runInlineTest }) => { test('should work with destructured array', async ({ runInlineTest }) => {
const { results } = await runInlineTest({ const { results } = await runInlineTest({
'a.test.js': ` 'a.test.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
asdf: async ({}, test) => await test(['foo', 'bar', { baz: 'baz' }]), asdf: async ({}, test) => await test(['foo', 'bar', { baz: 'baz' }]),
more: async ({}, test) => await test(55), more: async ({}, test) => await test(55),
}); });
@ -154,8 +162,9 @@ test('should work with destructured array', async ({ runInlineTest }) => {
test('should fail if parameters are not destructured', async ({ runInlineTest }) => { test('should fail if parameters are not destructured', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
asdf: async ({}, test) => await test(123), asdf: async ({}, test) => await test(123),
}); });
test('should pass', function () { test('should pass', function () {
@ -167,30 +176,32 @@ test('should fail if parameters are not destructured', async ({ runInlineTest })
`, `,
}); });
expect(result.output).toContain('First argument must use the object destructuring pattern: abc'); expect(result.output).toContain('First argument must use the object destructuring pattern: abc');
expect(result.output).toContain('a.test.js:11'); expect(result.output).toContain('a.test.ts:9');
expect(result.output).toContain('function (abc)'); expect(result.output).toContain('function (abc)');
expect(result.results.length).toBe(0); expect(result.results.length).toBe(0);
}); });
test('should fail with an unknown fixture', async ({ runInlineTest }) => { test('should fail with an unknown fixture', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.ts': `
pwt.test('should use asdf', async ({asdf}) => { import { test, expect } from '@playwright/test';
test('should use asdf', async ({asdf}) => {
expect(asdf).toBe(123); expect(asdf).toBe(123);
}); });
`, `,
}); });
expect(result.output).toContain('Test has unknown parameter "asdf".'); expect(result.output).toContain('Test has unknown parameter "asdf".');
expect(result.output).toContain('a.test.js:5'); expect(result.output).toContain('a.test.ts:3');
expect(result.output).toContain('async ({asdf})'); expect(result.output).toContain('async ({asdf})');
expect(result.results.length).toBe(0); expect(result.results.length).toBe(0);
}); });
test('should run the fixture every time', async ({ runInlineTest }) => { test('should run the fixture every time', async ({ runInlineTest }) => {
const { results } = await runInlineTest({ const { results } = await runInlineTest({
'a.test.js': ` 'a.test.ts': `
import { test as base, expect } from '@playwright/test';
let counter = 0; let counter = 0;
const test = pwt.test.extend({ const test = base.extend({
asdf: async ({}, test) => await test(counter++), asdf: async ({}, test) => await test(counter++),
}); });
test('should use asdf 1', async ({asdf}) => { test('should use asdf 1', async ({asdf}) => {
@ -209,9 +220,10 @@ test('should run the fixture every time', async ({ runInlineTest }) => {
test('should only run worker fixtures once', async ({ runInlineTest }) => { test('should only run worker fixtures once', async ({ runInlineTest }) => {
const { results } = await runInlineTest({ const { results } = await runInlineTest({
'a.test.js': ` 'a.test.ts': `
let counter = 0; let counter = 0;
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
asdf: [ async ({}, test) => await test(counter++), { scope: 'worker' } ], asdf: [ async ({}, test) => await test(counter++), { scope: 'worker' } ],
}); });
test('should use asdf 1', async ({asdf}) => { test('should use asdf 1', async ({asdf}) => {
@ -230,8 +242,9 @@ test('should only run worker fixtures once', async ({ runInlineTest }) => {
test('each file should get their own fixtures', async ({ runInlineTest }) => { test('each file should get their own fixtures', async ({ runInlineTest }) => {
const { results } = await runInlineTest({ const { results } = await runInlineTest({
'a.test.js': ` 'a.test.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
worker: [ async ({}, test) => await test('worker-a'), { scope: 'worker' } ], worker: [ async ({}, test) => await test('worker-a'), { scope: 'worker' } ],
test: async ({}, test) => await test('test-a'), test: async ({}, test) => await test('test-a'),
}); });
@ -240,8 +253,9 @@ test('each file should get their own fixtures', async ({ runInlineTest }) => {
expect(test).toBe('test-a'); expect(test).toBe('test-a');
}); });
`, `,
'b.test.js': ` 'b.test.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
worker: [ async ({}, test) => await test('worker-b'), { scope: 'worker' } ], worker: [ async ({}, test) => await test('worker-b'), { scope: 'worker' } ],
test: async ({}, test) => await test('test-b'), test: async ({}, test) => await test('test-b'),
}); });
@ -250,8 +264,9 @@ test('each file should get their own fixtures', async ({ runInlineTest }) => {
expect(test).toBe('test-b'); expect(test).toBe('test-b');
}); });
`, `,
'c.test.js': ` 'c.test.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
worker: [ async ({}, test) => await test('worker-c'), { scope: 'worker' } ], worker: [ async ({}, test) => await test('worker-c'), { scope: 'worker' } ],
test: async ({}, test) => await test('test-c'), test: async ({}, test) => await test('test-c'),
}); });
@ -268,25 +283,26 @@ test('tests should be able to share worker fixtures', async ({ runInlineTest })
const { results } = await runInlineTest({ const { results } = await runInlineTest({
'worker.js': ` 'worker.js': `
global.counter = 0; global.counter = 0;
const test = pwt.test.extend({ const { test: base, expect } = require('@playwright/test');
const test = base.extend({
worker: [ async ({}, test) => await test(global.counter++), { scope: 'worker' } ], worker: [ async ({}, test) => await test(global.counter++), { scope: 'worker' } ],
}); });
module.exports = test; module.exports = { test, expect };
`, `,
'a.test.js': ` 'a.test.ts': `
const test = require('./worker.js'); const { test, expect } = require('./worker.js');
test('should use worker', async ({worker}) => { test('should use worker', async ({worker}) => {
expect(worker).toBe(0); expect(worker).toBe(0);
}); });
`, `,
'b.test.js': ` 'b.test.ts': `
const test = require('./worker.js'); const { test, expect } = require('./worker.js');
test('should use worker', async ({worker}) => { test('should use worker', async ({worker}) => {
expect(worker).toBe(0); expect(worker).toBe(0);
}); });
`, `,
'c.test.js': ` 'c.test.ts': `
const test = require('./worker.js'); const { test, expect } = require('./worker.js');
test('should use worker', async ({worker}) => { test('should use worker', async ({worker}) => {
expect(worker).toBe(0); expect(worker).toBe(0);
}); });
@ -297,11 +313,11 @@ test('tests should be able to share worker fixtures', async ({ runInlineTest })
test('automatic fixtures should work', async ({ runInlineTest }) => { test('automatic fixtures should work', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.ts': `
import { test, expect } from '@playwright/test';
let counterTest = 0; let counterTest = 0;
let counterHooksIncluded = 0; let counterHooksIncluded = 0;
let counterWorker = 0; let counterWorker = 0;
const test = pwt.test;
test.use({ test.use({
automaticTestFixture: [ async ({}, runTest) => { automaticTestFixture: [ async ({}, runTest) => {
++counterTest; ++counterTest;
@ -356,8 +372,8 @@ test('automatic fixtures should work', async ({ runInlineTest }) => {
test('automatic fixture should start before regular fixture and teardown after', async ({ runInlineTest }) => { test('automatic fixture should start before regular fixture and teardown after', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.ts': `
const test = pwt.test; import { test, expect } from '@playwright/test';
test.use({ test.use({
auto: [ async ({}, runTest) => { auto: [ async ({}, runTest) => {
console.log('\\n%%auto-setup'); console.log('\\n%%auto-setup');
@ -385,8 +401,8 @@ test('automatic fixture should start before regular fixture and teardown after',
test('automatic fixtures should keep workerInfo after conditional skip', async ({ runInlineTest }) => { test('automatic fixtures should keep workerInfo after conditional skip', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.ts': `
const test = pwt.test; import { test, expect } from '@playwright/test';
test.use({ test.use({
automaticTestFixture: [ async ({}, runTest, workerInfo) => { automaticTestFixture: [ async ({}, runTest, workerInfo) => {
await runTest(); await runTest();
@ -413,9 +429,10 @@ test('automatic fixtures should keep workerInfo after conditional skip', async (
test('tests does not run non-automatic worker fixtures', async ({ runInlineTest }) => { test('tests does not run non-automatic worker fixtures', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.ts': `
let counter = 0; let counter = 0;
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
nonAutomaticWorkerFixture: [ async ({}, runTest) => { nonAutomaticWorkerFixture: [ async ({}, runTest) => {
++counter; ++counter;
await runTest(); await runTest();
@ -435,7 +452,8 @@ test('should teardown fixtures after timeout', async ({ runInlineTest }, testInf
require('fs').writeFileSync(file, '', 'utf8'); require('fs').writeFileSync(file, '', 'utf8');
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
file: [ ${JSON.stringify(file)}, { scope: 'worker' } ], file: [ ${JSON.stringify(file)}, { scope: 'worker' } ],
w: [ async ({ file }, runTest) => { w: [ async ({ file }, runTest) => {
await runTest('w'); await runTest('w');
@ -461,11 +479,12 @@ test('should teardown fixtures after timeout', async ({ runInlineTest }, testInf
test('should work with two different test objects', async ({ runInlineTest }) => { test('should work with two different test objects', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.ts': `
const test1 = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test1 = base.extend({
foo: async ({}, test) => await test(123), foo: async ({}, test) => await test(123),
}); });
const test2 = pwt.test.extend({ const test2 = base.extend({
bar: async ({}, test) => await test(456), bar: async ({}, test) => await test(456),
}); });
test1('test 1', async ({foo}) => { test1('test 1', async ({foo}) => {
@ -482,8 +501,9 @@ test('should work with two different test objects', async ({ runInlineTest }) =>
test('should work with overrides calling base', async ({ runInlineTest }) => { test('should work with overrides calling base', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.ts': `
const test1 = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test1 = base.extend({
dep: async ({}, test) => await test('override'), dep: async ({}, test) => await test('override'),
foo: async ({}, test) => await test('base'), foo: async ({}, test) => await test('base'),
bar: async ({foo}, test) => await test(foo + '-bar'), bar: async ({foo}, test) => await test(foo + '-bar'),
@ -504,8 +524,9 @@ test('should work with overrides calling base', async ({ runInlineTest }) => {
test('should understand worker fixture params in overrides calling base', async ({ runInlineTest }) => { test('should understand worker fixture params in overrides calling base', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.ts': `
const test1 = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test1 = base.extend({
param: [ 'param', { scope: 'worker', option: true }], param: [ 'param', { scope: 'worker', option: true }],
}).extend({ }).extend({
foo: async ({}, test) => await test('foo'), foo: async ({}, test) => await test('foo'),
@ -535,8 +556,9 @@ test('should understand worker fixture params in overrides calling base', async
test('should work with two overrides calling base', async ({ runInlineTest }) => { test('should work with two overrides calling base', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.ts': `
const test1 = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test1 = base.extend({
foo: async ({}, test) => await test('foo'), foo: async ({}, test) => await test('foo'),
bar: async ({}, test) => await test('bar'), bar: async ({}, test) => await test('bar'),
baz: async ({foo, bar}, test) => await test(foo + '-baz-' + bar), baz: async ({foo, bar}, test) => await test(foo + '-baz-' + bar),
@ -556,7 +578,7 @@ test('should work with two overrides calling base', async ({ runInlineTest }) =>
test('should not create a new worker for test fixtures', async ({ runInlineTest }) => { test('should not create a new worker for test fixtures', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('base test', async ({}, testInfo) => { test('base test', async ({}, testInfo) => {
expect(testInfo.workerIndex).toBe(0); expect(testInfo.workerIndex).toBe(0);
}); });
@ -572,7 +594,7 @@ test('should not create a new worker for test fixtures', async ({ runInlineTest
}); });
`, `,
'b.test.ts': ` 'b.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
const test2 = test.extend({ const test2 = test.extend({
foo: async ({}, run) => { foo: async ({}, run) => {
console.log('foo-b'); console.log('foo-b');
@ -599,7 +621,7 @@ test('should not create a new worker for test fixtures', async ({ runInlineTest
test('should create a new worker for worker fixtures', async ({ runInlineTest }) => { test('should create a new worker for worker fixtures', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('base test', async ({}, testInfo) => { test('base test', async ({}, testInfo) => {
console.log('\\n%%base-' + testInfo.workerIndex); console.log('\\n%%base-' + testInfo.workerIndex);
}); });
@ -615,7 +637,7 @@ test('should create a new worker for worker fixtures', async ({ runInlineTest })
}); });
`, `,
'b.test.ts': ` 'b.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
const test2 = test.extend({ const test2 = test.extend({
bar: async ({}, run) => { bar: async ({}, run) => {
console.log('bar-b'); console.log('bar-b');
@ -639,7 +661,7 @@ test('should create a new worker for worker fixtures', async ({ runInlineTest })
test('should run tests in order', async ({ runInlineTest }) => { test('should run tests in order', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test1', async ({}, testInfo) => { test('test1', async ({}, testInfo) => {
expect(testInfo.workerIndex).toBe(0); expect(testInfo.workerIndex).toBe(0);
console.log('\\n%%test1'); console.log('\\n%%test1');
@ -675,8 +697,8 @@ test('should run tests in order', async ({ runInlineTest }) => {
test('worker fixture should not receive TestInfo', async ({ runInlineTest }) => { test('worker fixture should not receive TestInfo', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.ts': `
const test = pwt.test; import { test, expect } from '@playwright/test';
test.use({ test.use({
worker: [async ({}, use, info) => { worker: [async ({}, use, info) => {
expect(info.title).toBe(undefined); expect(info.title).toBe(undefined);
@ -696,8 +718,9 @@ test('worker fixture should not receive TestInfo', async ({ runInlineTest }) =>
test('worker teardown errors reflected in timed-out tests', async ({ runInlineTest }) => { test('worker teardown errors reflected in timed-out tests', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
foo: [async ({}, use) => { foo: [async ({}, use) => {
let cb; let cb;
await use(new Promise((f, r) => cb = r)); await use(new Promise((f, r) => cb = r));

View File

@ -20,11 +20,11 @@ test('should respect .gitignore', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'.gitignore': `a.spec.js`, '.gitignore': `a.spec.js`,
'a.spec.js': ` 'a.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
`, `,
'b.spec.js': ` 'b.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
` `
}); });
@ -36,11 +36,11 @@ test('should respect nested .gitignore', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a/.gitignore': `a.spec.js`, 'a/.gitignore': `a.spec.js`,
'a/a.spec.js': ` 'a/a.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
`, `,
'a/b.spec.js': ` 'a/b.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
` `
}); });
@ -52,11 +52,11 @@ test('should respect enclosing .gitignore', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'.gitignore': `a/a.spec.js`, '.gitignore': `a/a.spec.js`,
'a/a.spec.js': ` 'a/a.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
`, `,
'a/b.spec.js': ` 'a/b.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
` `
}); });
@ -74,30 +74,30 @@ test('should respect negations and comments in .gitignore', async ({ runInlineTe
!dir1/foo/a.spec.js !dir1/foo/a.spec.js
`, `,
'a.spec.js': ` 'a.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => console.log('\\n%%a.spec.js')); test('pass', ({}) => console.log('\\n%%a.spec.js'));
`, `,
'dir1/a.spec.js': ` 'dir1/a.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => console.log('\\n%%dir1/a.spec.js')); test('pass', ({}) => console.log('\\n%%dir1/a.spec.js'));
`, `,
'dir1/foo/a.spec.js': ` 'dir1/foo/a.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => console.log('\\n%%dir1/foo/a.spec.js')); test('pass', ({}) => console.log('\\n%%dir1/foo/a.spec.js'));
`, `,
'dir2/a.spec.js': ` 'dir2/a.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => console.log('\\n%%dir2/a.spec.js')); test('pass', ({}) => console.log('\\n%%dir2/a.spec.js'));
`, `,
'dir3/.gitignore': ` 'dir3/.gitignore': `
b.*.js b.*.js
`, `,
'dir3/a.spec.js': ` 'dir3/a.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => console.log('\\n%%dir3/a.spec.js')); test('pass', ({}) => console.log('\\n%%dir3/a.spec.js'));
`, `,
'dir3/b.spec.js': ` 'dir3/b.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => console.log('\\n%%dir3/b.spec.js')); test('pass', ({}) => console.log('\\n%%dir3/b.spec.js'));
`, `,
}, { workers: 1 }); }, { workers: 1 });
@ -121,11 +121,11 @@ test('should ignore .gitignore inside globally configured testDir', async ({ run
}; };
`, `,
'tests/a.spec.js': ` 'tests/a.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
`, `,
'tests/foo/b.spec.js': ` 'tests/foo/b.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
` `
}); });
@ -145,11 +145,11 @@ test('should ignore .gitignore inside project testDir', async ({ runInlineTest }
] }; ] };
`, `,
'tests/a.spec.js': ` 'tests/a.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
`, `,
'tests/foo/b.spec.js': ` 'tests/foo/b.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
` `
}); });

View File

@ -38,7 +38,7 @@ test('globalSetup and globalTeardown should work', async ({ runInlineTest }) =>
}; };
`, `,
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('should work', async ({}, testInfo) => { test('should work', async ({}, testInfo) => {
console.log('\\n%%from-test'); console.log('\\n%%from-test');
}); });
@ -67,7 +67,7 @@ test('standalone globalTeardown should work', async ({ runInlineTest }) => {
}; };
`, `,
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('should work', async ({}, testInfo) => { test('should work', async ({}, testInfo) => {
}); });
`, `,
@ -98,7 +98,7 @@ test('globalTeardown runs after failures', async ({ runInlineTest }) => {
}; };
`, `,
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('should work', async ({}, testInfo) => { test('should work', async ({}, testInfo) => {
expect(process.env.FOO).toBe('43'); expect(process.env.FOO).toBe('43');
}); });
@ -129,7 +129,7 @@ test('globalTeardown does not run when globalSetup times out', async ({ runInlin
}; };
`, `,
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('should not run', async ({}, testInfo) => { test('should not run', async ({}, testInfo) => {
}); });
`, `,
@ -152,7 +152,7 @@ test('globalSetup should work with sync function', async ({ runInlineTest }) =>
}; };
`, `,
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('should work', async ({}) => { test('should work', async ({}) => {
const value = JSON.parse(process.env.FOO); const value = JSON.parse(process.env.FOO);
expect(value).toEqual({ foo: 'bar' }); expect(value).toEqual({ foo: 'bar' });
@ -176,7 +176,7 @@ test('globalSetup error should prevent tests from executing', async ({ runInline
}; };
`, `,
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('a', async ({}) => { test('a', async ({}) => {
console.log('this test ran'); console.log('this test ran');
}); });
@ -203,7 +203,7 @@ test('globalSetup should throw when passed non-function', async ({ runInlineTest
module.exports = 42; module.exports = 42;
`, `,
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('should work', async ({}) => { test('should work', async ({}) => {
}); });
`, `,
@ -231,7 +231,7 @@ test('globalSetup should work with default export and run the returned fn', asyn
export default setup; export default setup;
`, `,
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('should work', async ({}) => { test('should work', async ({}) => {
}); });
`, `,
@ -258,7 +258,7 @@ test('globalSetup should allow requiring a package from node_modules', async ({
}; };
`, `,
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('should work', async ({}, testInfo) => { test('should work', async ({}, testInfo) => {
expect(process.env.FOO).toBe('42'); expect(process.env.FOO).toBe('42');
}); });
@ -269,7 +269,8 @@ test('globalSetup should allow requiring a package from node_modules', async ({
const authFiles = { const authFiles = {
'playwright.config.ts': ` 'playwright.config.ts': `
const config: pwt.PlaywrightTestConfig = { import { PlaywrightTestConfig } from '@playwright/test';
const config: PlaywrightTestConfig = {
globalSetup: require.resolve('./auth'), globalSetup: require.resolve('./auth'),
use: { use: {
baseURL: 'https://www.example.com', baseURL: 'https://www.example.com',
@ -279,9 +280,10 @@ const authFiles = {
export default config; export default config;
`, `,
'auth.ts': ` 'auth.ts': `
async function globalSetup(config: pwt.FullConfig) { import { chromium, FullConfig } from '@playwright/test';
async function globalSetup(config: FullConfig) {
const { baseURL, storageState } = config.projects[0].use; const { baseURL, storageState } = config.projects[0].use;
const browser = await pwt.chromium.launch(); const browser = await chromium.launch();
const page = await browser.newPage(); const page = await browser.newPage();
await page.route('**/*', route => { await page.route('**/*', route => {
route.fulfill({ body: '<html></html>' }).catch(() => {}); route.fulfill({ body: '<html></html>' }).catch(() => {});
@ -296,7 +298,7 @@ const authFiles = {
export default globalSetup; export default globalSetup;
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('should have storage state', async ({ page }) => { test('should have storage state', async ({ page }) => {
await page.route('**/*', route => { await page.route('**/*', route => {
route.fulfill({ body: '<html></html>' }).catch(() => {}); route.fulfill({ body: '<html></html>' }).catch(() => {});
@ -331,8 +333,9 @@ test('teardown order', async ({ runInlineTest }) => {
} }
export default { _plugins }; export default { _plugins };
`, `,
'a.test.js': ` 'a.test.ts': `
pwt.test('test', () => {}); import { test, expect } from '@playwright/test';
test('test', () => {});
`, `,
}); });
expect(result.exitCode).toBe(0); expect(result.exitCode).toBe(0);
@ -362,8 +365,9 @@ test('teardown after error', async ({ runInlineTest }) => {
} }
export default { _plugins }; export default { _plugins };
`, `,
'a.test.js': ` 'a.test.ts': `
pwt.test('test', () => {}); import { test, expect } from '@playwright/test';
test('test', () => {});
`, `,
}); });
expect(result.exitCode).toBe(1); expect(result.exitCode).toBe(1);

View File

@ -21,7 +21,9 @@ import { test, expect, createWhiteImage, paintBlackPixels } from './playwright-t
const files = { const files = {
'helper.ts': ` 'helper.ts': `
export const test = pwt.test.extend({ import { test as base } from '@playwright/test';
export { expect } from '@playwright/test';
export const test = base.extend({
auto: [ async ({}, run, testInfo) => { auto: [ async ({}, run, testInfo) => {
testInfo.snapshotSuffix = ''; testInfo.snapshotSuffix = '';
await run(); await run();
@ -35,7 +37,7 @@ test('should support golden', async ({ runInlineTest }) => {
...files, ...files,
'a.spec.js-snapshots/snapshot.txt': `Hello world`, 'a.spec.js-snapshots/snapshot.txt': `Hello world`,
'a.spec.js': ` 'a.spec.js': `
const { test } = require('./helper'); const { test, expect } = require('./helper');
test('is a test', ({}) => { test('is a test', ({}) => {
expect('Hello world').toMatchSnapshot('snapshot.txt'); expect('Hello world').toMatchSnapshot('snapshot.txt');
}); });
@ -49,7 +51,7 @@ test('should work with non-txt extensions', async ({ runInlineTest }) => {
...files, ...files,
'a.spec.js-snapshots/snapshot.csv': `1,2,3`, 'a.spec.js-snapshots/snapshot.csv': `1,2,3`,
'a.spec.js': ` 'a.spec.js': `
const { test } = require('./helper'); const { test, expect } = require('./helper');
test('is a test', ({}) => { test('is a test', ({}) => {
expect('1,2,4').toMatchSnapshot('snapshot.csv'); expect('1,2,4').toMatchSnapshot('snapshot.csv');
}); });
@ -64,7 +66,7 @@ test('should generate default name', async ({ runInlineTest }, testInfo) => {
const result = await runInlineTest({ const result = await runInlineTest({
...files, ...files,
'a.spec.js': ` 'a.spec.js': `
const { test } = require('./helper'); const { test, expect } = require('./helper');
test('is a test', async ({ page }) => { test('is a test', async ({ page }) => {
expect.soft('foo').toMatchSnapshot(); expect.soft('foo').toMatchSnapshot();
expect.soft('bar').toMatchSnapshot(); expect.soft('bar').toMatchSnapshot();
@ -91,7 +93,7 @@ test('should generate default name', async ({ runInlineTest }, testInfo) => {
test('should compile with different option combinations', async ({ runTSC }) => { test('should compile with different option combinations', async ({ runTSC }) => {
const result = await runTSC({ const result = await runTSC({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('is a test', async ({ page }) => { test('is a test', async ({ page }) => {
expect('foo').toMatchSnapshot(); expect('foo').toMatchSnapshot();
expect('foo').toMatchSnapshot({ threshold: 0.2 }); expect('foo').toMatchSnapshot({ threshold: 0.2 });
@ -114,7 +116,7 @@ Line5
Line6 Line6
Line7`, Line7`,
'a.spec.js': ` 'a.spec.js': `
const { test } = require('./helper'); const { test, expect } = require('./helper');
test('is a test', ({}) => { test('is a test', ({}) => {
const data = []; const data = [];
data.push('Line1'); data.push('Line1');
@ -142,7 +144,7 @@ test('should write detailed failure result to an output folder', async ({ runInl
...files, ...files,
'a.spec.js-snapshots/snapshot.txt': `Hello world`, 'a.spec.js-snapshots/snapshot.txt': `Hello world`,
'a.spec.js': ` 'a.spec.js': `
const { test } = require('./helper'); const { test, expect } = require('./helper');
test('is a test', ({}) => { test('is a test', ({}) => {
expect('Hello world updated').toMatchSnapshot('snapshot.txt'); expect('Hello world updated').toMatchSnapshot('snapshot.txt');
}); });
@ -165,7 +167,7 @@ test("doesn\'t create comparison artifacts in an output folder for passed negate
...files, ...files,
'a.spec.js-snapshots/snapshot.txt': `Hello world`, 'a.spec.js-snapshots/snapshot.txt': `Hello world`,
'a.spec.js': ` 'a.spec.js': `
const { test } = require('./helper'); const { test, expect } = require('./helper');
test('is a test', ({}) => { test('is a test', ({}) => {
expect('Hello world updated').not.toMatchSnapshot('snapshot.txt'); expect('Hello world updated').not.toMatchSnapshot('snapshot.txt');
}); });
@ -187,7 +189,7 @@ test('should fail on same snapshots with negate matcher', async ({ runInlineTest
...files, ...files,
'a.spec.js-snapshots/snapshot.txt': `Hello world`, 'a.spec.js-snapshots/snapshot.txt': `Hello world`,
'a.spec.js': ` 'a.spec.js': `
const { test } = require('./helper'); const { test, expect } = require('./helper');
test('is a test', ({}) => { test('is a test', ({}) => {
expect('Hello world').not.toMatchSnapshot('snapshot.txt'); expect('Hello world').not.toMatchSnapshot('snapshot.txt');
}); });
@ -203,7 +205,7 @@ test('should write missing expectations locally twice and continue', async ({ ru
const result = await runInlineTest({ const result = await runInlineTest({
...files, ...files,
'a.spec.js': ` 'a.spec.js': `
const { test } = require('./helper'); const { test, expect } = require('./helper');
test('is a test', ({}) => { test('is a test', ({}) => {
expect('Hello world').toMatchSnapshot('snapshot.txt'); expect('Hello world').toMatchSnapshot('snapshot.txt');
expect('Hello world2').toMatchSnapshot('snapshot2.txt'); expect('Hello world2').toMatchSnapshot('snapshot2.txt');
@ -226,7 +228,7 @@ test('should write missing expectations locally twice and continue', async ({ ru
expect(result.output).toContain('Here we are!'); expect(result.output).toContain('Here we are!');
const stackLines = result.output.split('\n').filter(line => line.includes(' at ')).filter(line => !line.includes(testInfo.outputPath())); const stackLines = result.output.split('\n').filter(line => line.includes(' at ')).filter(line => !line.includes(testInfo.outputPath()));
expect(result.output).toContain('a.spec.js:8'); expect(result.output).toContain('a.spec.js:4');
expect(stackLines.length).toBe(0); expect(stackLines.length).toBe(0);
}); });
@ -234,7 +236,7 @@ test('should not write missing expectations for negated matcher', async ({ runIn
const result = await runInlineTest({ const result = await runInlineTest({
...files, ...files,
'a.spec.js': ` 'a.spec.js': `
const { test } = require('./helper'); const { test, expect } = require('./helper');
test('is a test', ({}) => { test('is a test', ({}) => {
expect('Hello world').not.toMatchSnapshot('snapshot.txt'); expect('Hello world').not.toMatchSnapshot('snapshot.txt');
}); });
@ -254,7 +256,7 @@ test('should update snapshot with the update-snapshots flag', async ({ runInline
...files, ...files,
'a.spec.js-snapshots/snapshot.txt': EXPECTED_SNAPSHOT, 'a.spec.js-snapshots/snapshot.txt': EXPECTED_SNAPSHOT,
'a.spec.js': ` 'a.spec.js': `
const { test } = require('./helper'); const { test, expect } = require('./helper');
test('is a test', ({}) => { test('is a test', ({}) => {
expect('${ACTUAL_SNAPSHOT}').toMatchSnapshot('snapshot.txt'); expect('${ACTUAL_SNAPSHOT}').toMatchSnapshot('snapshot.txt');
}); });
@ -275,7 +277,7 @@ test('should ignore text snapshot with the ignore-snapshots flag', async ({ runI
...files, ...files,
'a.spec.js-snapshots/snapshot.txt': EXPECTED_SNAPSHOT, 'a.spec.js-snapshots/snapshot.txt': EXPECTED_SNAPSHOT,
'a.spec.js': ` 'a.spec.js': `
const { test } = require('./helper'); const { test, expect } = require('./helper');
test('is a test', ({}) => { test('is a test', ({}) => {
expect('${ACTUAL_SNAPSHOT}').toMatchSnapshot('snapshot.txt'); expect('${ACTUAL_SNAPSHOT}').toMatchSnapshot('snapshot.txt');
}); });
@ -296,7 +298,7 @@ test('shouldn\'t update snapshot with the update-snapshots flag for negated matc
...files, ...files,
'a.spec.js-snapshots/snapshot.txt': EXPECTED_SNAPSHOT, 'a.spec.js-snapshots/snapshot.txt': EXPECTED_SNAPSHOT,
'a.spec.js': ` 'a.spec.js': `
const { test } = require('./helper'); const { test, expect } = require('./helper');
test('is a test', ({}) => { test('is a test', ({}) => {
expect('${ACTUAL_SNAPSHOT}').not.toMatchSnapshot('snapshot.txt'); expect('${ACTUAL_SNAPSHOT}').not.toMatchSnapshot('snapshot.txt');
}); });
@ -314,7 +316,7 @@ test('should silently write missing expectations locally with the update-snapsho
const result = await runInlineTest({ const result = await runInlineTest({
...files, ...files,
'a.spec.js': ` 'a.spec.js': `
const { test } = require('./helper'); const { test, expect } = require('./helper');
test('is a test', ({}) => { test('is a test', ({}) => {
expect('${ACTUAL_SNAPSHOT}').toMatchSnapshot('snapshot.txt'); expect('${ACTUAL_SNAPSHOT}').toMatchSnapshot('snapshot.txt');
}); });
@ -332,7 +334,7 @@ test('should silently write missing expectations locally with the update-snapsho
const result = await runInlineTest({ const result = await runInlineTest({
...files, ...files,
'a.spec.js': ` 'a.spec.js': `
const { test } = require('./helper'); const { test, expect } = require('./helper');
test('is a test', ({}) => { test('is a test', ({}) => {
expect('Hello world').not.toMatchSnapshot('snapshot.txt'); expect('Hello world').not.toMatchSnapshot('snapshot.txt');
}); });
@ -352,7 +354,7 @@ test('should match multiple snapshots', async ({ runInlineTest }) => {
'a.spec.js-snapshots/snapshot2.txt': `Snapshot2`, 'a.spec.js-snapshots/snapshot2.txt': `Snapshot2`,
'a.spec.js-snapshots/snapshot3.txt': `Snapshot3`, 'a.spec.js-snapshots/snapshot3.txt': `Snapshot3`,
'a.spec.js': ` 'a.spec.js': `
const { test } = require('./helper'); const { test, expect } = require('./helper');
test('is a test', ({}) => { test('is a test', ({}) => {
expect('Snapshot1').toMatchSnapshot('snapshot1.txt'); expect('Snapshot1').toMatchSnapshot('snapshot1.txt');
expect('Snapshot2').toMatchSnapshot('snapshot2.txt'); expect('Snapshot2').toMatchSnapshot('snapshot2.txt');
@ -374,14 +376,14 @@ test('should match snapshots from multiple projects', async ({ runInlineTest })
]}; ]};
`, `,
'p1/a.spec.js': ` 'p1/a.spec.js': `
const { test } = require('../helper'); const { test, expect } = require('../helper');
test('is a test', ({}) => { test('is a test', ({}) => {
expect('Snapshot1').toMatchSnapshot('snapshot.txt'); expect('Snapshot1').toMatchSnapshot('snapshot.txt');
}); });
`, `,
'p1/a.spec.js-snapshots/snapshot.txt': `Snapshot1`, 'p1/a.spec.js-snapshots/snapshot.txt': `Snapshot1`,
'p2/a.spec.js': ` 'p2/a.spec.js': `
const { test } = require('../helper'); const { test, expect } = require('../helper');
test('is a test', ({}) => { test('is a test', ({}) => {
expect('Snapshot2').toMatchSnapshot('snapshot.txt'); expect('Snapshot2').toMatchSnapshot('snapshot.txt');
}); });
@ -396,7 +398,7 @@ test('should use provided name', async ({ runInlineTest }) => {
...files, ...files,
'a.spec.js-snapshots/provided.txt': `Hello world`, 'a.spec.js-snapshots/provided.txt': `Hello world`,
'a.spec.js': ` 'a.spec.js': `
const { test } = require('./helper'); const { test, expect } = require('./helper');
test('is a test', ({}) => { test('is a test', ({}) => {
expect('Hello world').toMatchSnapshot('provided.txt'); expect('Hello world').toMatchSnapshot('provided.txt');
}); });
@ -410,7 +412,7 @@ test('should use provided name via options', async ({ runInlineTest }) => {
...files, ...files,
'a.spec.js-snapshots/provided.txt': `Hello world`, 'a.spec.js-snapshots/provided.txt': `Hello world`,
'a.spec.js': ` 'a.spec.js': `
const { test } = require('./helper'); const { test, expect } = require('./helper');
test('is a test', ({}) => { test('is a test', ({}) => {
expect('Hello world').toMatchSnapshot({ name: 'provided.txt' }); expect('Hello world').toMatchSnapshot({ name: 'provided.txt' });
}); });
@ -424,7 +426,7 @@ test('should compare binary', async ({ runInlineTest }) => {
...files, ...files,
'a.spec.js-snapshots/snapshot.dat': Buffer.from([1, 2, 3, 4]), 'a.spec.js-snapshots/snapshot.dat': Buffer.from([1, 2, 3, 4]),
'a.spec.js': ` 'a.spec.js': `
const { test } = require('./helper'); const { test, expect } = require('./helper');
test('is a test', ({}) => { test('is a test', ({}) => {
expect(Buffer.from([1,2,3,4])).toMatchSnapshot('snapshot.dat'); expect(Buffer.from([1,2,3,4])).toMatchSnapshot('snapshot.dat');
}); });
@ -444,7 +446,7 @@ test('should respect maxDiffPixels option', async ({ runInlineTest }) => {
...files, ...files,
'a.spec.js-snapshots/snapshot.png': image1, 'a.spec.js-snapshots/snapshot.png': image1,
'a.spec.js': ` 'a.spec.js': `
const { test } = require('./helper'); const { test, expect } = require('./helper');
test('is a test', ({}) => { test('is a test', ({}) => {
expect(Buffer.from('${image2.toString('base64')}', 'base64')).toMatchSnapshot('snapshot.png'); expect(Buffer.from('${image2.toString('base64')}', 'base64')).toMatchSnapshot('snapshot.png');
}); });
@ -459,7 +461,7 @@ test('should respect maxDiffPixels option', async ({ runInlineTest }) => {
...files, ...files,
'a.spec.js-snapshots/snapshot.png': image1, 'a.spec.js-snapshots/snapshot.png': image1,
'a.spec.js': ` 'a.spec.js': `
const { test } = require('./helper'); const { test, expect } = require('./helper');
test('is a test', ({}) => { test('is a test', ({}) => {
expect(Buffer.from('${image2.toString('base64')}', 'base64')).toMatchSnapshot('snapshot.png', { expect(Buffer.from('${image2.toString('base64')}', 'base64')).toMatchSnapshot('snapshot.png', {
maxDiffPixels: ${BAD_PIXELS} maxDiffPixels: ${BAD_PIXELS}
@ -477,7 +479,7 @@ test('should respect maxDiffPixels option', async ({ runInlineTest }) => {
`, `,
'a.spec.js-snapshots/snapshot.png': image1, 'a.spec.js-snapshots/snapshot.png': image1,
'a.spec.js': ` 'a.spec.js': `
const { test } = require('./helper'); const { test, expect } = require('./helper');
test('is a test', ({}) => { test('is a test', ({}) => {
expect(Buffer.from('${image2.toString('base64')}', 'base64')).toMatchSnapshot('snapshot.png'); expect(Buffer.from('${image2.toString('base64')}', 'base64')).toMatchSnapshot('snapshot.png');
}); });
@ -496,7 +498,7 @@ test('should respect maxDiffPixelRatio option', async ({ runInlineTest }) => {
...files, ...files,
'a.spec.js-snapshots/snapshot.png': image1, 'a.spec.js-snapshots/snapshot.png': image1,
'a.spec.js': ` 'a.spec.js': `
const { test } = require('./helper'); const { test, expect } = require('./helper');
test('is a test', ({}) => { test('is a test', ({}) => {
expect(Buffer.from('${image2.toString('base64')}', 'base64')).toMatchSnapshot('snapshot.png'); expect(Buffer.from('${image2.toString('base64')}', 'base64')).toMatchSnapshot('snapshot.png');
}); });
@ -507,7 +509,7 @@ test('should respect maxDiffPixelRatio option', async ({ runInlineTest }) => {
...files, ...files,
'a.spec.js-snapshots/snapshot.png': image1, 'a.spec.js-snapshots/snapshot.png': image1,
'a.spec.js': ` 'a.spec.js': `
const { test } = require('./helper'); const { test, expect } = require('./helper');
test('is a test', ({}) => { test('is a test', ({}) => {
expect(Buffer.from('${image2.toString('base64')}', 'base64')).toMatchSnapshot('snapshot.png', { expect(Buffer.from('${image2.toString('base64')}', 'base64')).toMatchSnapshot('snapshot.png', {
maxDiffPixelRatio: ${BAD_RATIO} maxDiffPixelRatio: ${BAD_RATIO}
@ -525,7 +527,7 @@ test('should respect maxDiffPixelRatio option', async ({ runInlineTest }) => {
`, `,
'a.spec.js-snapshots/snapshot.png': image1, 'a.spec.js-snapshots/snapshot.png': image1,
'a.spec.js': ` 'a.spec.js': `
const { test } = require('./helper'); const { test, expect } = require('./helper');
test('is a test', ({}) => { test('is a test', ({}) => {
expect(Buffer.from('${image2.toString('base64')}', 'base64')).toMatchSnapshot('snapshot.png'); expect(Buffer.from('${image2.toString('base64')}', 'base64')).toMatchSnapshot('snapshot.png');
}); });
@ -539,7 +541,7 @@ test('should compare PNG images', async ({ runInlineTest }) => {
'a.spec.js-snapshots/snapshot.png': 'a.spec.js-snapshots/snapshot.png':
Buffer.from('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+P+/HgAFhAJ/wlseKgAAAABJRU5ErkJggg==', 'base64'), Buffer.from('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+P+/HgAFhAJ/wlseKgAAAABJRU5ErkJggg==', 'base64'),
'a.spec.js': ` 'a.spec.js': `
const { test } = require('./helper'); const { test, expect } = require('./helper');
test('is a test', ({}) => { test('is a test', ({}) => {
expect(Buffer.from('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+P+/HgAFhAJ/wlseKgAAAABJRU5ErkJggg==', 'base64')).toMatchSnapshot('snapshot.png'); expect(Buffer.from('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+P+/HgAFhAJ/wlseKgAAAABJRU5ErkJggg==', 'base64')).toMatchSnapshot('snapshot.png');
}); });
@ -554,7 +556,7 @@ test('should compare different PNG images', async ({ runInlineTest }, testInfo)
'a.spec.js-snapshots/snapshot.png': 'a.spec.js-snapshots/snapshot.png':
Buffer.from('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+P+/HgAFhAJ/wlseKgAAAABJRU5ErkJggg==', 'base64'), Buffer.from('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+P+/HgAFhAJ/wlseKgAAAABJRU5ErkJggg==', 'base64'),
'a.spec.js': ` 'a.spec.js': `
const { test } = require('./helper'); const { test, expect } = require('./helper');
test('is a test', ({}) => { test('is a test', ({}) => {
expect(Buffer.from('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVQYV2NgYAAAAAMAAWgmWQ0AAAAASUVORK5CYII==', 'base64')).toMatchSnapshot('snapshot.png'); expect(Buffer.from('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVQYV2NgYAAAAAMAAWgmWQ0AAAAASUVORK5CYII==', 'base64')).toMatchSnapshot('snapshot.png');
}); });
@ -583,7 +585,7 @@ test('should respect threshold', async ({ runInlineTest }) => {
'a.spec.js-snapshots/snapshot.png': expected, 'a.spec.js-snapshots/snapshot.png': expected,
'a.spec.js-snapshots/snapshot2.png': expected, 'a.spec.js-snapshots/snapshot2.png': expected,
'a.spec.js': ` 'a.spec.js': `
const { test } = require('./helper'); const { test, expect } = require('./helper');
test('is a test', ({}) => { test('is a test', ({}) => {
expect(Buffer.from('${actual.toString('base64')}', 'base64')).toMatchSnapshot('snapshot.png', { threshold: 0.3 }); expect(Buffer.from('${actual.toString('base64')}', 'base64')).toMatchSnapshot('snapshot.png', { threshold: 0.3 });
expect(Buffer.from('${actual.toString('base64')}', 'base64')).not.toMatchSnapshot('snapshot.png', { threshold: 0.2 }); expect(Buffer.from('${actual.toString('base64')}', 'base64')).not.toMatchSnapshot('snapshot.png', { threshold: 0.2 });
@ -608,7 +610,7 @@ test('should respect project threshold', async ({ runInlineTest }) => {
'a.spec.js-snapshots/snapshot.png': expected, 'a.spec.js-snapshots/snapshot.png': expected,
'a.spec.js-snapshots/snapshot2.png': expected, 'a.spec.js-snapshots/snapshot2.png': expected,
'a.spec.js': ` 'a.spec.js': `
const { test } = require('./helper'); const { test, expect } = require('./helper');
test('is a test', ({}) => { test('is a test', ({}) => {
expect(Buffer.from('${actual.toString('base64')}', 'base64')).toMatchSnapshot('snapshot.png', { threshold: 0.3 }); expect(Buffer.from('${actual.toString('base64')}', 'base64')).toMatchSnapshot('snapshot.png', { threshold: 0.3 });
expect(Buffer.from('${actual.toString('base64')}', 'base64')).not.toMatchSnapshot('snapshot.png'); expect(Buffer.from('${actual.toString('base64')}', 'base64')).not.toMatchSnapshot('snapshot.png');
@ -627,7 +629,7 @@ test('should respect comparator name', async ({ runInlineTest }) => {
...files, ...files,
'a.spec.js-snapshots/snapshot.png': expected, 'a.spec.js-snapshots/snapshot.png': expected,
'a.spec.js': ` 'a.spec.js': `
const { test } = require('./helper'); const { test, expect } = require('./helper');
test('should pass', ({}) => { test('should pass', ({}) => {
expect(Buffer.from('${actual.toString('base64')}', 'base64')).toMatchSnapshot('snapshot.png', { expect(Buffer.from('${actual.toString('base64')}', 'base64')).toMatchSnapshot('snapshot.png', {
threshold: 0, threshold: 0,
@ -679,7 +681,7 @@ test('should respect comparator in config', async ({ runInlineTest }) => {
`, `,
'__screenshots__/a.spec.js/snapshot.png': expected, '__screenshots__/a.spec.js/snapshot.png': expected,
'a.spec.js': ` 'a.spec.js': `
const { test } = require('./helper'); const { test, expect } = require('./helper');
test('test', ({}) => { test('test', ({}) => {
expect(Buffer.from('${actual.toString('base64')}', 'base64')).toMatchSnapshot('snapshot.png', { expect(Buffer.from('${actual.toString('base64')}', 'base64')).toMatchSnapshot('snapshot.png', {
threshold: 0, threshold: 0,
@ -699,7 +701,7 @@ test('should sanitize snapshot name when passed as string', async ({ runInlineTe
...files, ...files,
'a.spec.js-snapshots/-snapshot-.txt': `Hello world`, 'a.spec.js-snapshots/-snapshot-.txt': `Hello world`,
'a.spec.js': ` 'a.spec.js': `
const { test } = require('./helper');; const { test, expect } = require('./helper');;
test('is a test', ({}) => { test('is a test', ({}) => {
expect('Hello world').toMatchSnapshot('../../snapshot!.txt'); expect('Hello world').toMatchSnapshot('../../snapshot!.txt');
}); });
@ -712,7 +714,7 @@ test('should write missing expectations with sanitized snapshot name', async ({
const result = await runInlineTest({ const result = await runInlineTest({
...files, ...files,
'a.spec.js': ` 'a.spec.js': `
const { test } = require('./helper');; const { test, expect } = require('./helper');;
test('is a test', ({}) => { test('is a test', ({}) => {
expect('Hello world').toMatchSnapshot('../../snapshot!.txt'); expect('Hello world').toMatchSnapshot('../../snapshot!.txt');
}); });
@ -731,7 +733,7 @@ test('should join array of snapshot path segments without sanitizing', async ({
...files, ...files,
'a.spec.js-snapshots/test/path/snapshot.txt': `Hello world`, 'a.spec.js-snapshots/test/path/snapshot.txt': `Hello world`,
'a.spec.js': ` 'a.spec.js': `
const { test } = require('./helper'); const { test, expect } = require('./helper');
test('is a test', ({}) => { test('is a test', ({}) => {
expect('Hello world').toMatchSnapshot(['test', 'path', 'snapshot.txt']); expect('Hello world').toMatchSnapshot(['test', 'path', 'snapshot.txt']);
}); });
@ -750,7 +752,7 @@ test('should use snapshotDir as snapshot base directory', async ({ runInlineTest
`, `,
'snaps/a.spec.js-snapshots/snapshot.txt': `Hello world`, 'snaps/a.spec.js-snapshots/snapshot.txt': `Hello world`,
'a.spec.js': ` 'a.spec.js': `
const { test } = require('./helper'); const { test, expect } = require('./helper');
test('is a test', ({}) => { test('is a test', ({}) => {
expect('Hello world').toMatchSnapshot('snapshot.txt'); expect('Hello world').toMatchSnapshot('snapshot.txt');
}); });
@ -769,7 +771,7 @@ test('should use snapshotDir with path segments as snapshot directory', async ({
`, `,
'snaps/tests/a.spec.js-snapshots/test/path/snapshot.txt': `Hello world`, 'snaps/tests/a.spec.js-snapshots/test/path/snapshot.txt': `Hello world`,
'tests/a.spec.js': ` 'tests/a.spec.js': `
const { test } = require('../helper'); const { test, expect } = require('../helper');
test('is a test', ({}) => { test('is a test', ({}) => {
expect('Hello world').toMatchSnapshot(['test', 'path', 'snapshot.txt']); expect('Hello world').toMatchSnapshot(['test', 'path', 'snapshot.txt']);
}); });
@ -788,7 +790,7 @@ test('should use snapshotDir with nested test suite and path segments', async ({
`, `,
'snaps/path/to/tests/a.spec.js-snapshots/path/to/snapshot.txt': `Hello world`, 'snaps/path/to/tests/a.spec.js-snapshots/path/to/snapshot.txt': `Hello world`,
'path/to/tests/a.spec.js': ` 'path/to/tests/a.spec.js': `
const { test } = require('../../../helper'); const { test, expect } = require('../../../helper');
test('is a test', ({}) => { test('is a test', ({}) => {
expect('Hello world').toMatchSnapshot(['path', 'to', 'snapshot.txt']); expect('Hello world').toMatchSnapshot(['path', 'to', 'snapshot.txt']);
}); });
@ -800,7 +802,9 @@ test('should use snapshotDir with nested test suite and path segments', async ({
test('should use project snapshotDir over base snapshotDir', async ({ runInlineTest }) => { test('should use project snapshotDir over base snapshotDir', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'helper.ts': ` 'helper.ts': `
export const test = pwt.test.extend({ import { test as base } from '@playwright/test';
export { expect } from '@playwright/test';
export const test = base.extend({
auto: [ async ({}, run, testInfo) => { auto: [ async ({}, run, testInfo) => {
testInfo.snapshotSuffix = 'suffix'; testInfo.snapshotSuffix = 'suffix';
await run(); await run();
@ -820,7 +824,7 @@ test('should use project snapshotDir over base snapshotDir', async ({ runInlineT
`, `,
'project_snaps/a.spec.js-snapshots/test/path/snapshot-foo-suffix.txt': `Hello world`, 'project_snaps/a.spec.js-snapshots/test/path/snapshot-foo-suffix.txt': `Hello world`,
'a.spec.js': ` 'a.spec.js': `
const { test } = require('./helper'); const { test, expect } = require('./helper');
test('is a test', ({}) => { test('is a test', ({}) => {
expect('Hello world').toMatchSnapshot(['test', 'path', 'snapshot.txt']); expect('Hello world').toMatchSnapshot(['test', 'path', 'snapshot.txt']);
}); });
@ -833,7 +837,7 @@ test('should update snapshot with array of path segments', async ({ runInlineTes
const result = await runInlineTest({ const result = await runInlineTest({
...files, ...files,
'a.spec.js': ` 'a.spec.js': `
const { test } = require('./helper'); const { test, expect } = require('./helper');
test('is a test', ({}) => { test('is a test', ({}) => {
expect('Hello world').toMatchSnapshot(['test', 'path', 'snapshot.txt']); expect('Hello world').toMatchSnapshot(['test', 'path', 'snapshot.txt']);
}); });
@ -853,7 +857,7 @@ test('should attach expected/actual/diff with snapshot path', async ({ runInline
'a.spec.js-snapshots/test/path/snapshot.png': 'a.spec.js-snapshots/test/path/snapshot.png':
Buffer.from('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+P+/HgAFhAJ/wlseKgAAAABJRU5ErkJggg==', 'base64'), Buffer.from('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+P+/HgAFhAJ/wlseKgAAAABJRU5ErkJggg==', 'base64'),
'a.spec.js': ` 'a.spec.js': `
const { test } = require('./helper'); const { test, expect } = require('./helper');
test.afterEach(async ({}, testInfo) => { test.afterEach(async ({}, testInfo) => {
console.log('## ' + JSON.stringify(testInfo.attachments)); console.log('## ' + JSON.stringify(testInfo.attachments));
}); });
@ -894,7 +898,7 @@ test('should attach expected/actual/diff', async ({ runInlineTest }, testInfo) =
'a.spec.js-snapshots/snapshot.png': 'a.spec.js-snapshots/snapshot.png':
Buffer.from('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+P+/HgAFhAJ/wlseKgAAAABJRU5ErkJggg==', 'base64'), Buffer.from('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+P+/HgAFhAJ/wlseKgAAAABJRU5ErkJggg==', 'base64'),
'a.spec.js': ` 'a.spec.js': `
const { test } = require('./helper'); const { test, expect } = require('./helper');
test.afterEach(async ({}, testInfo) => { test.afterEach(async ({}, testInfo) => {
console.log('## ' + JSON.stringify(testInfo.attachments)); console.log('## ' + JSON.stringify(testInfo.attachments));
}); });
@ -933,7 +937,7 @@ test('should attach expected/actual/diff for different sizes', async ({ runInlin
'a.spec.js-snapshots/snapshot.png': 'a.spec.js-snapshots/snapshot.png':
Buffer.from('iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAEklEQVR42mP8z8AARAwMjDAGACwBA/9IB8FMAAAAAElFTkSuQmCC', 'base64'), Buffer.from('iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAEklEQVR42mP8z8AARAwMjDAGACwBA/9IB8FMAAAAAElFTkSuQmCC', 'base64'),
'a.spec.js': ` 'a.spec.js': `
const { test } = require('./helper'); const { test, expect } = require('./helper');
test.afterEach(async ({}, testInfo) => { test.afterEach(async ({}, testInfo) => {
console.log('## ' + JSON.stringify(testInfo.attachments)); console.log('## ' + JSON.stringify(testInfo.attachments));
}); });
@ -975,7 +979,7 @@ test('should fail with missing expectations and retries', async ({ runInlineTest
module.exports = { retries: 1 }; module.exports = { retries: 1 };
`, `,
'a.spec.js': ` 'a.spec.js': `
const { test } = require('./helper'); const { test, expect } = require('./helper');
test('is a test', ({}) => { test('is a test', ({}) => {
expect('Hello world').toMatchSnapshot('snapshot.txt'); expect('Hello world').toMatchSnapshot('snapshot.txt');
}); });
@ -997,7 +1001,7 @@ test('should update expectations with retries', async ({ runInlineTest }, testIn
module.exports = { retries: 1 }; module.exports = { retries: 1 };
`, `,
'a.spec.js': ` 'a.spec.js': `
const { test } = require('./helper'); const { test, expect } = require('./helper');
test('is a test', ({}) => { test('is a test', ({}) => {
expect('Hello world').toMatchSnapshot('snapshot.txt'); expect('Hello world').toMatchSnapshot('snapshot.txt');
}); });
@ -1017,7 +1021,7 @@ test('should allow comparing text with text without file extension', async ({ ru
...files, ...files,
'a.spec.js-snapshots/snapshot-no-extension': `Hello world`, 'a.spec.js-snapshots/snapshot-no-extension': `Hello world`,
'a.spec.js': ` 'a.spec.js': `
const { test } = require('./helper'); const { test, expect } = require('./helper');
test('is a test', ({}) => { test('is a test', ({}) => {
expect('Hello world').toMatchSnapshot('snapshot-no-extension'); expect('Hello world').toMatchSnapshot('snapshot-no-extension');
}); });
@ -1030,7 +1034,7 @@ test('should throw if a Promise was passed to toMatchSnapshot', async ({ runInli
const result = await runInlineTest({ const result = await runInlineTest({
...files, ...files,
'a.spec.js': ` 'a.spec.js': `
const { test } = require('./helper'); const { test, expect } = require('./helper');
test('is a test', ({}) => { test('is a test', ({}) => {
expect(() => expect(new Promise(() => {})).toMatchSnapshot('foobar')).toThrow(/An unresolved Promise was passed to toMatchSnapshot\\(\\), make sure to resolve it by adding await to it./); expect(() => expect(new Promise(() => {})).toMatchSnapshot('foobar')).toThrow(/An unresolved Promise was passed to toMatchSnapshot\\(\\), make sure to resolve it by adding await to it./);
}); });

View File

@ -19,9 +19,11 @@ import { test, expect } from './playwright-test-fixtures';
test('hooks should work with fixtures', async ({ runInlineTest }) => { test('hooks should work with fixtures', async ({ runInlineTest }) => {
const { results } = await runInlineTest({ const { results } = await runInlineTest({
'helper.ts': ` 'helper.ts': `
import { test as base } from '@playwright/test';
export { expect } from '@playwright/test';
global.logs = []; global.logs = [];
let counter = 0; let counter = 0;
export const test = pwt.test.extend({ export const test = base.extend({
w: [ async ({}, run) => { w: [ async ({}, run) => {
global.logs.push('+w'); global.logs.push('+w');
await run(17); await run(17);
@ -37,7 +39,7 @@ test('hooks should work with fixtures', async ({ runInlineTest }) => {
}); });
`, `,
'a.test.js': ` 'a.test.js': `
const { test } = require('./helper'); const { test, expect } = require('./helper');
test.describe('suite', () => { test.describe('suite', () => {
test.beforeAll(async ({ w, t }) => { test.beforeAll(async ({ w, t }) => {
global.logs.push('beforeAll-' + w + '-' + t); global.logs.push('beforeAll-' + w + '-' + t);
@ -79,8 +81,10 @@ test('hooks should work with fixtures', async ({ runInlineTest }) => {
test('afterEach failure should not prevent other hooks and fixtures teardown', async ({ runInlineTest }) => { test('afterEach failure should not prevent other hooks and fixtures teardown', async ({ runInlineTest }) => {
const report = await runInlineTest({ const report = await runInlineTest({
'helper.ts': ` 'helper.ts': `
import { test as base } from '@playwright/test';
export { expect } from '@playwright/test';
global.logs = []; global.logs = [];
export const test = pwt.test.extend({ export const test = base.extend({
foo: async ({}, run) => { foo: async ({}, run) => {
console.log('+t'); console.log('+t');
await run(); await run();
@ -89,7 +93,7 @@ test('afterEach failure should not prevent other hooks and fixtures teardown', a
}); });
`, `,
'a.test.js': ` 'a.test.js': `
const { test } = require('./helper'); const { test, expect } = require('./helper');
test.describe('suite', () => { test.describe('suite', () => {
test.afterEach(async () => { test.afterEach(async () => {
console.log('afterEach2'); console.log('afterEach2');
@ -112,7 +116,7 @@ test('afterEach failure should not prevent other hooks and fixtures teardown', a
test('beforeEach failure should prevent the test, but not other hooks', async ({ runInlineTest }) => { test('beforeEach failure should prevent the test, but not other hooks', async ({ runInlineTest }) => {
const report = await runInlineTest({ const report = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.describe('suite', () => { test.describe('suite', () => {
test.beforeEach(async ({}) => { test.beforeEach(async ({}) => {
console.log('beforeEach1'); console.log('beforeEach1');
@ -137,7 +141,7 @@ test('beforeEach failure should prevent the test, but not other hooks', async ({
test('beforeAll should be run once', async ({ runInlineTest }) => { test('beforeAll should be run once', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.describe('suite1', () => { test.describe('suite1', () => {
let counter = 0; let counter = 0;
test.beforeAll(async () => { test.beforeAll(async () => {
@ -164,7 +168,7 @@ test('beforeAll should be run once', async ({ runInlineTest }) => {
test('beforeEach should be able to skip a test', async ({ runInlineTest }) => { test('beforeEach should be able to skip a test', async ({ runInlineTest }) => {
const { passed, skipped, exitCode } = await runInlineTest({ const { passed, skipped, exitCode } = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.beforeEach(async ({}, testInfo) => { test.beforeEach(async ({}, testInfo) => {
testInfo.skip(testInfo.title === 'test2'); testInfo.skip(testInfo.title === 'test2');
}); });
@ -180,7 +184,8 @@ test('beforeEach should be able to skip a test', async ({ runInlineTest }) => {
test('beforeAll from a helper file should throw', async ({ runInlineTest }) => { test('beforeAll from a helper file should throw', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'my-test.ts': ` 'my-test.ts': `
export const test = pwt.test; import { test as base, expect } from '@playwright/test';
export const test = base;
test.beforeAll(() => {}); test.beforeAll(() => {});
`, `,
'playwright.config.ts': ` 'playwright.config.ts': `
@ -200,7 +205,7 @@ test('beforeAll from a helper file should throw', async ({ runInlineTest }) => {
test('beforeAll hooks are skipped when no tests in the suite are run', async ({ runInlineTest }) => { test('beforeAll hooks are skipped when no tests in the suite are run', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.describe('suite1', () => { test.describe('suite1', () => {
test.beforeAll(() => { test.beforeAll(() => {
console.log('\\n%%beforeAll1'); console.log('\\n%%beforeAll1');
@ -224,7 +229,7 @@ test('beforeAll hooks are skipped when no tests in the suite are run', async ({
test('beforeAll/afterAll hooks are skipped when no tests in the suite are run 2', async ({ runInlineTest }) => { test('beforeAll/afterAll hooks are skipped when no tests in the suite are run 2', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.beforeAll(() => { test.beforeAll(() => {
console.log('\\n%%beforeAll1'); console.log('\\n%%beforeAll1');
}); });
@ -253,7 +258,7 @@ test('beforeAll/afterAll hooks are skipped when no tests in the suite are run 2'
test('run hooks after failure', async ({ runInlineTest }) => { test('run hooks after failure', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.describe('suite', () => { test.describe('suite', () => {
test('faled', ({}) => { test('faled', ({}) => {
console.log('\\n%%test'); console.log('\\n%%test');
@ -290,7 +295,7 @@ test('run hooks after failure', async ({ runInlineTest }) => {
test('beforeAll hook should get retry index of the first test', async ({ runInlineTest }) => { test('beforeAll hook should get retry index of the first test', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.beforeAll(({}, testInfo) => { test.beforeAll(({}, testInfo) => {
console.log('\\n%%beforeall-retry-' + testInfo.retry); console.log('\\n%%beforeall-retry-' + testInfo.retry);
}); });
@ -313,7 +318,7 @@ test('beforeAll hook should get retry index of the first test', async ({ runInli
test('afterAll exception should fail the test', async ({ runInlineTest }) => { test('afterAll exception should fail the test', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.afterAll(() => { test.afterAll(() => {
throw new Error('From the afterAll'); throw new Error('From the afterAll');
}); });
@ -330,7 +335,7 @@ test('afterAll exception should fail the test', async ({ runInlineTest }) => {
test('max-failures should still run afterEach/afterAll', async ({ runInlineTest }) => { test('max-failures should still run afterEach/afterAll', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.js': ` 'a.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.afterAll(() => { test.afterAll(() => {
console.log('\\n%%afterAll'); console.log('\\n%%afterAll');
}); });
@ -360,7 +365,7 @@ test('max-failures should still run afterEach/afterAll', async ({ runInlineTest
test('beforeAll failure should prevent the test, but not afterAll', async ({ runInlineTest }) => { test('beforeAll failure should prevent the test, but not afterAll', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.beforeAll(() => { test.beforeAll(() => {
console.log('\\n%%beforeAll'); console.log('\\n%%beforeAll');
throw new Error('From a beforeAll'); throw new Error('From a beforeAll');
@ -388,7 +393,8 @@ test('beforeAll failure should prevent the test, but not afterAll', async ({ run
test('fixture error should not prevent afterAll', async ({ runInlineTest }) => { test('fixture error should not prevent afterAll', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
foo: async ({}, use) => { foo: async ({}, use) => {
await use('foo'); await use('foo');
throw new Error('bad fixture'); throw new Error('bad fixture');
@ -414,7 +420,7 @@ test('fixture error should not prevent afterAll', async ({ runInlineTest }) => {
test('afterEach failure should not prevent afterAll', async ({ runInlineTest }) => { test('afterEach failure should not prevent afterAll', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('good test', ({ }) => { test('good test', ({ }) => {
console.log('\\n%%test'); console.log('\\n%%test');
}); });
@ -440,7 +446,7 @@ test('afterEach failure should not prevent afterAll', async ({ runInlineTest })
test('afterAll error should not mask beforeAll', async ({ runInlineTest }) => { test('afterAll error should not mask beforeAll', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.beforeAll(() => { test.beforeAll(() => {
throw new Error('from beforeAll'); throw new Error('from beforeAll');
}); });
@ -459,7 +465,7 @@ test('afterAll error should not mask beforeAll', async ({ runInlineTest }) => {
test('beforeAll timeout should be reported and prevent more tests', async ({ runInlineTest }) => { test('beforeAll timeout should be reported and prevent more tests', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.beforeAll(async () => { test.beforeAll(async () => {
console.log('\\n%%beforeAll'); console.log('\\n%%beforeAll');
await new Promise(f => setTimeout(f, 5000)); await new Promise(f => setTimeout(f, 5000));
@ -483,14 +489,14 @@ test('beforeAll timeout should be reported and prevent more tests', async ({ run
'afterAll', 'afterAll',
]); ]);
expect(result.output).toContain('"beforeAll" hook timeout of 1000ms exceeded.'); expect(result.output).toContain('"beforeAll" hook timeout of 1000ms exceeded.');
expect(result.output).toContain(`a.test.js:6:12`); expect(result.output).toContain(`a.test.js:3:12`);
expect(result.output).toContain(`> 6 | test.beforeAll(async () => {`); expect(result.output).toContain(`> 3 | test.beforeAll(async () => {`);
}); });
test('afterAll timeout should be reported, run other afterAll hooks, and continue testing', async ({ runInlineTest }, testInfo) => { test('afterAll timeout should be reported, run other afterAll hooks, and continue testing', async ({ runInlineTest }, testInfo) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.describe('suite', () => { test.describe('suite', () => {
test.afterAll(async () => { test.afterAll(async () => {
console.log('\\n%%afterAll1'); console.log('\\n%%afterAll1');
@ -521,14 +527,14 @@ test('afterAll timeout should be reported, run other afterAll hooks, and continu
'afterAll2', 'afterAll2',
]); ]);
expect(result.output).toContain('"afterAll" hook timeout of 1000ms exceeded.'); expect(result.output).toContain('"afterAll" hook timeout of 1000ms exceeded.');
expect(result.output).toContain(`a.test.js:7:14`); expect(result.output).toContain(`a.test.js:4:14`);
expect(result.output).toContain(`> 7 | test.afterAll(async () => {`); expect(result.output).toContain(`> 4 | test.afterAll(async () => {`);
}); });
test('beforeAll and afterAll timeouts at the same time should be reported', async ({ runInlineTest }) => { test('beforeAll and afterAll timeouts at the same time should be reported', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.beforeAll(async () => { test.beforeAll(async () => {
console.log('\\n%%beforeAll'); console.log('\\n%%beforeAll');
await new Promise(f => setTimeout(f, 5000)); await new Promise(f => setTimeout(f, 5000));
@ -554,7 +560,7 @@ test('beforeAll and afterAll timeouts at the same time should be reported', asyn
test('afterEach should get the test status and duration right away', async ({ runInlineTest }) => { test('afterEach should get the test status and duration right away', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.afterEach(({}, testInfo) => { test.afterEach(({}, testInfo) => {
const duration = testInfo.duration ? 'XXms' : 'none'; const duration = testInfo.duration ? 'XXms' : 'none';
console.log('\\n%%' + testInfo.title + ': ' + testInfo.status + '; ' + duration); console.log('\\n%%' + testInfo.title + ': ' + testInfo.status + '; ' + duration);
@ -579,7 +585,8 @@ test('afterEach should get the test status and duration right away', async ({ ru
test('uncaught error in beforeEach should not be masked by another error', async ({ runInlineTest }) => { test('uncaught error in beforeEach should not be masked by another error', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
foo: async ({}, use) => { foo: async ({}, use) => {
let cb; let cb;
await use(new Promise((f, r) => cb = r)); await use(new Promise((f, r) => cb = r));
@ -605,7 +612,8 @@ test('uncaught error in beforeEach should not be masked by another error', async
test('should report error from fixture teardown when beforeAll times out', async ({ runInlineTest }) => { test('should report error from fixture teardown when beforeAll times out', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
foo: async ({}, use) => { foo: async ({}, use) => {
let cb; let cb;
await use(new Promise((f, r) => cb = r)); await use(new Promise((f, r) => cb = r));
@ -628,7 +636,7 @@ test('should report error from fixture teardown when beforeAll times out', async
test('should not hang and report results when worker process suddenly exits during afterAll', async ({ runInlineTest }) => { test('should not hang and report results when worker process suddenly exits during afterAll', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.js': ` 'a.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('failing due to afterall', () => {}); test('failing due to afterall', () => {});
test.afterAll(() => { process.exit(0); }); test.afterAll(() => { process.exit(0); });
` `
@ -637,13 +645,13 @@ test('should not hang and report results when worker process suddenly exits duri
expect(result.passed).toBe(0); expect(result.passed).toBe(0);
expect(result.failed).toBe(1); expect(result.failed).toBe(1);
expect(result.output).toContain('Internal error: worker process exited unexpectedly'); expect(result.output).toContain('Internal error: worker process exited unexpectedly');
expect(result.output).toContain('[1/1] a.spec.js:6:7 failing due to afterall'); expect(result.output).toContain('[1/1] a.spec.js:3:11 failing due to afterall');
}); });
test('unhandled rejection during beforeAll should be reported and prevent more tests', async ({ runInlineTest }) => { test('unhandled rejection during beforeAll should be reported and prevent more tests', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.beforeAll(async () => { test.beforeAll(async () => {
console.log('\\n%%beforeAll'); console.log('\\n%%beforeAll');
Promise.resolve().then(() => { Promise.resolve().then(() => {
@ -670,13 +678,13 @@ test('unhandled rejection during beforeAll should be reported and prevent more t
'afterAll', 'afterAll',
]); ]);
expect(result.output).toContain('Error: Oh my'); expect(result.output).toContain('Error: Oh my');
expect(result.output).toContain(`> 9 | throw new Error('Oh my');`); expect(result.output).toContain(`> 6 | throw new Error('Oh my');`);
}); });
test('beforeAll and afterAll should have a separate timeout', async ({ runInlineTest }) => { test('beforeAll and afterAll should have a separate timeout', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.beforeAll(async () => { test.beforeAll(async () => {
console.log('\\n%%beforeAll'); console.log('\\n%%beforeAll');
await new Promise(f => setTimeout(f, 300)); await new Promise(f => setTimeout(f, 300));
@ -713,7 +721,7 @@ test('beforeAll and afterAll should have a separate timeout', async ({ runInline
test('test.setTimeout should work separately in beforeAll', async ({ runInlineTest }) => { test('test.setTimeout should work separately in beforeAll', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.beforeAll(async () => { test.beforeAll(async () => {
console.log('\\n%%beforeAll'); console.log('\\n%%beforeAll');
test.setTimeout(1000); test.setTimeout(1000);
@ -735,7 +743,7 @@ test('test.setTimeout should work separately in beforeAll', async ({ runInlineTe
test('test.setTimeout should work separately in afterAll', async ({ runInlineTest }) => { test('test.setTimeout should work separately in afterAll', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('passed', async () => { test('passed', async () => {
console.log('\\n%%test'); console.log('\\n%%test');
}); });
@ -757,7 +765,7 @@ test('test.setTimeout should work separately in afterAll', async ({ runInlineTes
test('beforeAll failure should only prevent tests that are affected', async ({ runInlineTest }) => { test('beforeAll failure should only prevent tests that are affected', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.describe('suite', () => { test.describe('suite', () => {
test.beforeAll(async () => { test.beforeAll(async () => {
console.log('\\n%%beforeAll'); console.log('\\n%%beforeAll');
@ -788,7 +796,7 @@ test('beforeAll failure should only prevent tests that are affected', async ({ r
test('afterAll should run if last test was skipped', async ({ runInlineTest }) => { test('afterAll should run if last test was skipped', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.afterAll(() => console.log('after-all')); test.afterAll(() => console.log('after-all'));
test('test1', () => {}); test('test1', () => {});
test.skip('test2', () => {}); test.skip('test2', () => {});
@ -803,7 +811,7 @@ test('afterAll should run if last test was skipped', async ({ runInlineTest }) =
test('afterAll should run if last test was skipped 2', async ({ runInlineTest }) => { test('afterAll should run if last test was skipped 2', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.afterAll(() => console.log('after-all')); test.afterAll(() => console.log('after-all'));
test('test1', () => {}); test('test1', () => {});
test('test2', () => { test.skip(); }); test('test2', () => { test.skip(); });
@ -818,7 +826,7 @@ test('afterAll should run if last test was skipped 2', async ({ runInlineTest })
test('afterEach timeout after skipped test should be reported', async ({ runInlineTest }) => { test('afterEach timeout after skipped test should be reported', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.afterEach(async () => { test.afterEach(async () => {
await new Promise(() => {}); await new Promise(() => {});
}); });
@ -833,7 +841,7 @@ test('afterEach timeout after skipped test should be reported', async ({ runInli
test('afterEach exception after skipped test should be reported', async ({ runInlineTest }) => { test('afterEach exception after skipped test should be reported', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.afterEach(async () => { test.afterEach(async () => {
throw new Error('oh my!'); throw new Error('oh my!');
}); });
@ -848,7 +856,7 @@ test('afterEach exception after skipped test should be reported', async ({ runIn
test('afterAll should be run for test.skip', async ({ runInlineTest }) => { test('afterAll should be run for test.skip', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.describe('suite1', () => { test.describe('suite1', () => {
test.beforeAll(() => console.log('\\n%%beforeAll1')); test.beforeAll(() => console.log('\\n%%beforeAll1'));
test.afterAll(() => console.log('\\n%%afterAll1')); test.afterAll(() => console.log('\\n%%afterAll1'));

View File

@ -24,7 +24,7 @@ test('should list tests', async ({ runInlineTest }) => {
module.exports = { projects: [{ name: 'foo' }, {}] }; module.exports = { projects: [{ name: 'foo' }, {}] };
`, `,
'a.test.js': ` 'a.test.js': `
const { test } = pwt; const { test, expect } = require('@playwright/test');
test('example1', async ({}) => { test('example1', async ({}) => {
expect(1 + 1).toBe(2); expect(1 + 1).toBe(2);
}); });
@ -36,10 +36,10 @@ test('should list tests', async ({ runInlineTest }) => {
expect(result.exitCode).toBe(0); expect(result.exitCode).toBe(0);
expect(result.output).toContain([ expect(result.output).toContain([
`Listing tests:`, `Listing tests:`,
` [foo] a.test.js:6:7 example1`, ` [foo] a.test.js:3:7 example1`,
` [foo] a.test.js:9:7 example2`, ` [foo] a.test.js:6:7 example2`,
` a.test.js:6:7 example1`, ` a.test.js:3:7 example1`,
` a.test.js:9:7 example2`, ` a.test.js:6:7 example2`,
`Total: 4 tests in 1 file` `Total: 4 tests in 1 file`
].join('\n')); ].join('\n'));
}); });
@ -50,7 +50,7 @@ test('should list tests to stdout when JSON reporter outputs to a file', async (
module.exports = { projects: [{ name: 'foo' }, {}] }; module.exports = { projects: [{ name: 'foo' }, {}] };
`, `,
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('example1', async ({}) => { test('example1', async ({}) => {
expect(1 + 1).toBe(2); expect(1 + 1).toBe(2);
}); });
@ -87,13 +87,13 @@ test('globalSetup and globalTeardown should not run', async ({ runInlineTest })
}; };
`, `,
'a.test.js': ` 'a.test.js': `
const { test } = pwt; const { test, expect } = require('@playwright/test');
test('should work 1', async ({}, testInfo) => { test('should work 1', async ({}, testInfo) => {
console.log('Running test 1'); console.log('Running test 1');
}); });
`, `,
'b.test.js': ` 'b.test.js': `
const { test } = pwt; const { test, expect } = require('@playwright/test');
test('should work 2', async ({}, testInfo) => { test('should work 2', async ({}, testInfo) => {
console.log('Running test 2'); console.log('Running test 2');
}); });
@ -102,8 +102,8 @@ test('globalSetup and globalTeardown should not run', async ({ runInlineTest })
expect(result.exitCode).toBe(0); expect(result.exitCode).toBe(0);
expect(result.output).toContain([ expect(result.output).toContain([
`Listing tests:`, `Listing tests:`,
` a.test.js:6:7 should work 1`, ` a.test.js:3:7 should work 1`,
` b.test.js:6:7 should work 2`, ` b.test.js:3:7 should work 2`,
`Total: 2 tests in 2 files`, `Total: 2 tests in 2 files`,
].join('\n')); ].join('\n'));
}); });
@ -116,7 +116,7 @@ test('outputDir should not be removed', async ({ runInlineTest }, testInfo) => {
module.exports = { outputDir: ${JSON.stringify(outputDir)} }; module.exports = { outputDir: ${JSON.stringify(outputDir)} };
`, `,
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('my test', async ({}, testInfo) => { test('my test', async ({}, testInfo) => {
console.log(testInfo.outputDir); console.log(testInfo.outputDir);
require('fs').writeFileSync(testInfo.outputPath('myfile.txt'), 'hello'); require('fs').writeFileSync(testInfo.outputPath('myfile.txt'), 'hello');
@ -131,7 +131,7 @@ test('outputDir should not be removed', async ({ runInlineTest }, testInfo) => {
module.exports = { outputDir: ${JSON.stringify(outputDir)} }; module.exports = { outputDir: ${JSON.stringify(outputDir)} };
`, `,
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('my test', async ({}, testInfo) => { test('my test', async ({}, testInfo) => {
console.log(testInfo.outputDir); console.log(testInfo.outputDir);
}); });
@ -149,13 +149,13 @@ test('should report errors', async ({ runInlineTest }) => {
` `
}, { 'list': true }); }, { 'list': true });
expect(result.exitCode).toBe(1); expect(result.exitCode).toBe(1);
expect(result.output).toContain('> 6 | oh = 2;'); expect(result.output).toContain('> 3 | oh = 2;');
}); });
test('should ignore .only', async ({ runInlineTest }) => { test('should ignore .only', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; const { test, expect } = require('@playwright/test');
test('example1', async ({}) => { test('example1', async ({}) => {
expect(1 + 1).toBe(2); expect(1 + 1).toBe(2);
}); });
@ -167,8 +167,8 @@ test('should ignore .only', async ({ runInlineTest }) => {
expect(result.exitCode).toBe(0); expect(result.exitCode).toBe(0);
expect(result.output).toContain([ expect(result.output).toContain([
`Listing tests:`, `Listing tests:`,
` a.test.js:6:7 example1`, ` a.test.js:3:7 example1`,
` a.test.js:9:12 example2`, ` a.test.js:6:12 example2`,
`Total: 2 tests in 1 file` `Total: 2 tests in 1 file`
].join('\n')); ].join('\n'));
}); });

View File

@ -29,7 +29,7 @@ test('should return the location of a syntax error', async ({ runInlineTest }) =
expect(result.passed).toBe(0); expect(result.passed).toBe(0);
expect(result.failed).toBe(0); expect(result.failed).toBe(0);
expect(result.output).toContain('error.spec.js'); expect(result.output).toContain('error.spec.js');
expect(result.output).toContain('(6:18)'); expect(result.output).toContain('(3:18)');
}); });
test('should return the location of a syntax error with deep stack', async ({ runInlineTest }) => { test('should return the location of a syntax error with deep stack', async ({ runInlineTest }) => {
@ -61,11 +61,11 @@ test('should return the location of a syntax error with deep stack', async ({ ru
`, `,
}); });
expect(result.exitCode).toBe(1); expect(result.exitCode).toBe(1);
expect(result.output).toContain('qux.ts:4:7'); expect(result.output).toContain('qux.ts:2:7');
expect(result.output).toContain('baz.ts:4:7'); expect(result.output).toContain('baz.ts:2:7');
expect(result.output).toContain('bar.ts:4:7'); expect(result.output).toContain('bar.ts:2:7');
expect(result.output).toContain('foo.ts:4:7'); expect(result.output).toContain('foo.ts:2:7');
expect(result.output).toContain('test.spec.ts:5:7'); expect(result.output).toContain('test.spec.ts:2:7');
}); });
test('should print an improper error', async ({ runInlineTest }) => { test('should print an improper error', async ({ runInlineTest }) => {
@ -115,7 +115,7 @@ test('should allow export default form the config file', async ({ runInlineTest
export default { timeout: 1000 }; export default { timeout: 1000 };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('fails', async ({}, testInfo) => { test('fails', async ({}, testInfo) => {
await new Promise(f => setTimeout(f, 2000)); await new Promise(f => setTimeout(f, 2000));
}); });
@ -133,7 +133,7 @@ test('should validate configuration object', async ({ runInlineTest }) => {
export default { timeout: '1000' }; export default { timeout: '1000' };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('works', () => {}); test('works', () => {});
` `
}); });
@ -146,39 +146,39 @@ test('should validate configuration object', async ({ runInlineTest }) => {
test('should match tests well', async ({ runInlineTest }) => { test('should match tests well', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('works', () => {}); test('works', () => {});
`, `,
'hello.spec.ts': ` 'hello.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('works', () => {}); test('works', () => {});
`, `,
'test.ts': ` 'test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('works', () => {}); test('works', () => {});
`, `,
'spec.ts': ` 'spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('works', () => {}); test('works', () => {});
`, `,
'strange.....spec.ts': ` 'strange.....spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('works', () => {}); test('works', () => {});
`, `,
'badspec.ts': ` 'badspec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('bad', () => { throw new Error('badspec.ts')}); test('bad', () => { throw new Error('badspec.ts')});
`, `,
'specspec.ts': ` 'specspec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('bad', () => { throw new Error('specspec.ts')}); test('bad', () => { throw new Error('specspec.ts')});
`, `,
'a.testtest.ts': ` 'a.testtest.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('bad', () => { throw new Error('a.testtest.ts')}); test('bad', () => { throw new Error('a.testtest.ts')});
`, `,
'b.testspec.ts': ` 'b.testspec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('bad', () => { throw new Error('b.testspec.ts')}); test('bad', () => { throw new Error('b.testspec.ts')});
` `
}); });
@ -190,7 +190,7 @@ test('should match tests well', async ({ runInlineTest }) => {
test('should load an mjs file', async ({ runInlineTest }) => { test('should load an mjs file', async ({ runInlineTest }) => {
const { exitCode, passed } = await runInlineTest({ const { exitCode, passed } = await runInlineTest({
'a.spec.mjs': ` 'a.spec.mjs': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('succeeds', () => { test('succeeds', () => {
expect(1 + 1).toBe(2); expect(1 + 1).toBe(2);
}); });
@ -204,7 +204,7 @@ test('should allow using import', async ({ runInlineTest }) => {
const { exitCode } = await runInlineTest({ const { exitCode } = await runInlineTest({
'a.spec.js': ` 'a.spec.js': `
import fs from 'fs'; import fs from 'fs';
const { test } = pwt; import { test, expect } from '@playwright/test';
test('succeeds', () => { test('succeeds', () => {
expect(1 + 1).toBe(2); expect(1 + 1).toBe(2);
}); });
@ -216,13 +216,12 @@ test('should allow using import', async ({ runInlineTest }) => {
test('should load esm when package.json has type module', async ({ runInlineTest }) => { test('should load esm when package.json has type module', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'playwright.config.js': ` 'playwright.config.js': `
//@no-header
import * as fs from 'fs'; import * as fs from 'fs';
export default { projects: [{name: 'foo'}] }; export default { projects: [{name: 'foo'}] };
`, `,
'package.json': JSON.stringify({ type: 'module' }), 'package.json': JSON.stringify({ type: 'module' }),
'a.esm.test.js': ` 'a.esm.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('check project name', ({}, testInfo) => { test('check project name', ({}, testInfo) => {
expect(testInfo.project.name).toBe('foo'); expect(testInfo.project.name).toBe('foo');
}); });
@ -236,12 +235,11 @@ test('should load esm when package.json has type module', async ({ runInlineTest
test('should load esm config files', async ({ runInlineTest }) => { test('should load esm config files', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'playwright.config.mjs': ` 'playwright.config.mjs': `
//@no-header
import * as fs from 'fs'; import * as fs from 'fs';
export default { projects: [{name: 'foo'}] }; export default { projects: [{name: 'foo'}] };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('check project name', ({}, testInfo) => { test('check project name', ({}, testInfo) => {
expect(testInfo.project.name).toBe('foo'); expect(testInfo.project.name).toBe('foo');
}); });
@ -257,13 +255,11 @@ test('should load ts from esm when package.json has type module', async ({ runIn
test.skip(nodeVersion.major < 16); test.skip(nodeVersion.major < 16);
const result = await runInlineTest({ const result = await runInlineTest({
'playwright.config.js': ` 'playwright.config.js': `
//@no-header
import * as fs from 'fs'; import * as fs from 'fs';
export default { projects: [{name: 'foo'}] }; export default { projects: [{name: 'foo'}] };
`, `,
'package.json': JSON.stringify({ type: 'module' }), 'package.json': JSON.stringify({ type: 'module' }),
'a.test.js': ` 'a.test.js': `
//@no-header
import { test, expect } from '@playwright/test'; import { test, expect } from '@playwright/test';
import { bar } from './bar.js'; import { bar } from './bar.js';
test('check project name', ({}, testInfo) => { test('check project name', ({}, testInfo) => {
@ -287,7 +283,7 @@ test('should load ts from esm when package.json has type module', async ({ runIn
test('should filter stack trace for simple expect', async ({ runInlineTest }) => { test('should filter stack trace for simple expect', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'expect-test.spec.ts': ` 'expect-test.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('should work', () => { test('should work', () => {
test.expect(1+1).toEqual(3); test.expect(1+1).toEqual(3);
}); });
@ -302,7 +298,7 @@ test('should filter stack trace for simple expect', async ({ runInlineTest }) =>
test('should filter stack trace for web-first assertions', async ({ runInlineTest }) => { test('should filter stack trace for web-first assertions', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'expect-test.spec.ts': ` 'expect-test.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('should work', async ({page}) => { test('should work', async ({page}) => {
await expect(page.locator('x-foo'), 'x-foo must be visible').toBeVisible({timeout: 1}); await expect(page.locator('x-foo'), 'x-foo must be visible').toBeVisible({timeout: 1});
}); });
@ -317,7 +313,7 @@ test('should filter stack trace for web-first assertions', async ({ runInlineTes
test('should filter out event emitter from stack traces', async ({ runInlineTest }, testInfo) => { test('should filter out event emitter from stack traces', async ({ runInlineTest }, testInfo) => {
const result = await runInlineTest({ const result = await runInlineTest({
'expect-test.spec.ts': ` 'expect-test.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
const EventEmitter = require('events'); const EventEmitter = require('events');
test('should work', async ({}) => { test('should work', async ({}) => {
const emitter = new EventEmitter(); const emitter = new EventEmitter();
@ -334,7 +330,7 @@ test('should filter out event emitter from stack traces', async ({ runInlineTest
test('should filter out syntax error stack traces', async ({ runInlineTest }, testInfo) => { test('should filter out syntax error stack traces', async ({ runInlineTest }, testInfo) => {
const result = await runInlineTest({ const result = await runInlineTest({
'expect-test.spec.ts': ` 'expect-test.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('should work', ({}) => { test('should work', ({}) => {
// syntax error: cannot have await in non-async function // syntax error: cannot have await in non-async function
await Proimse.resolve(); await Proimse.resolve();
@ -349,7 +345,7 @@ test('should filter out syntax error stack traces', async ({ runInlineTest }, te
test('should filter stack trace for raw errors', async ({ runInlineTest }) => { test('should filter stack trace for raw errors', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'expect-test.spec.ts': ` 'expect-test.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('should work', async ({}) => { test('should work', async ({}) => {
throw new Error('foobar!'); throw new Error('foobar!');
}); });
@ -370,7 +366,7 @@ test('should not filter out POM', async ({ runInlineTest }) => {
} }
`, `,
'expect-test.spec.ts': ` 'expect-test.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
const { foo } = require('./helper'); const { foo } = require('./helper');
test('should work', ({}) => { test('should work', ({}) => {
foo(); foo();
@ -389,7 +385,7 @@ test('should not filter out POM', async ({ runInlineTest }) => {
test('should filter stack even without default Error.prepareStackTrace', async ({ runInlineTest }) => { test('should filter stack even without default Error.prepareStackTrace', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'expect-test.spec.ts': ` 'expect-test.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('should work', ({}) => { test('should work', ({}) => {
Error.prepareStackTrace = undefined; Error.prepareStackTrace = undefined;
throw new Error('foobar'); throw new Error('foobar');
@ -409,7 +405,7 @@ test('should filter stack even without default Error.prepareStackTrace', async (
test('should work with cross-imports - 1', async ({ runInlineTest }) => { test('should work with cross-imports - 1', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'test1.spec.ts': ` 'test1.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test 1', async ({}) => { test('test 1', async ({}) => {
await new Promise(x => setTimeout(x, 500)); await new Promise(x => setTimeout(x, 500));
console.log('running TEST-1'); console.log('running TEST-1');
@ -417,7 +413,7 @@ test('should work with cross-imports - 1', async ({ runInlineTest }) => {
`, `,
'test2.spec.ts': ` 'test2.spec.ts': `
import * as _ from './test1.spec'; import * as _ from './test1.spec';
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test 2', async ({}) => { test('test 2', async ({}) => {
await new Promise(x => setTimeout(x, 500)); await new Promise(x => setTimeout(x, 500));
console.log('running TEST-2'); console.log('running TEST-2');
@ -434,7 +430,7 @@ test('should work with cross-imports - 1', async ({ runInlineTest }) => {
test('should work with cross-imports - 2', async ({ runInlineTest }) => { test('should work with cross-imports - 2', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'test1.spec.ts': ` 'test1.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
import * as _ from './test2.spec'; import * as _ from './test2.spec';
test('test 1', async ({}) => { test('test 1', async ({}) => {
await new Promise(x => setTimeout(x, 500)); await new Promise(x => setTimeout(x, 500));
@ -442,7 +438,7 @@ test('should work with cross-imports - 2', async ({ runInlineTest }) => {
}); });
`, `,
'test2.spec.ts': ` 'test2.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test 2', async ({}) => { test('test 2', async ({}) => {
await new Promise(x => setTimeout(x, 500)); await new Promise(x => setTimeout(x, 500));
console.log('running TEST-2'); console.log('running TEST-2');
@ -456,12 +452,11 @@ test('should work with cross-imports - 2', async ({ runInlineTest }) => {
expect(result.output).toContain('TEST-2'); expect(result.output).toContain('TEST-2');
}); });
test('should load web server w/o esm loader in ems module', async ({ runInlineTest, nodeVersion }) => { test('should load web server w/o esm loader in esm module', async ({ runInlineTest, nodeVersion }) => {
// We only support experimental esm mode on Node 16+ // We only support experimental esm mode on Node 16+
test.skip(nodeVersion.major < 16); test.skip(nodeVersion.major < 16);
const result = await runInlineTest({ const result = await runInlineTest({
'playwright.config.ts': ` 'playwright.config.ts': `
//@no-header
export default { export default {
webServer: { webServer: {
command: 'node ws.js', command: 'node ws.js',
@ -472,15 +467,14 @@ test('should load web server w/o esm loader in ems module', async ({ runInlineTe
}`, }`,
'package.json': `{ "type": "module" }`, 'package.json': `{ "type": "module" }`,
'ws.js': ` 'ws.js': `
//@no-header
console.log('NODE_OPTIONS ' + process.env.NODE_OPTIONS); console.log('NODE_OPTIONS ' + process.env.NODE_OPTIONS);
setTimeout(() => {}, 100000); setTimeout(() => {}, 100000);
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('passes', () => {}); test('passes', () => {});
` `
}, {}, { ...process.env, DEBUG: 'pw:webserver' }); }, {}, { DEBUG: 'pw:webserver' });
expect(result.exitCode).toBe(1); expect(result.exitCode).toBe(1);
expect(result.passed).toBe(0); expect(result.passed).toBe(0);
@ -490,14 +484,14 @@ test('should load web server w/o esm loader in ems module', async ({ runInlineTe
test('should load a jsx/tsx files', async ({ runInlineTest }) => { test('should load a jsx/tsx files', async ({ runInlineTest }) => {
const { exitCode, passed } = await runInlineTest({ const { exitCode, passed } = await runInlineTest({
'a.spec.tsx': ` 'a.spec.tsx': `
const { test } = pwt; import { test, expect } from '@playwright/test';
const component = () => <div></div>; const component = () => <div></div>;
test('succeeds', () => { test('succeeds', () => {
expect(1 + 1).toBe(2); expect(1 + 1).toBe(2);
}); });
`, `,
'b.spec.jsx': ` 'b.spec.jsx': `
const { test } = pwt; import { test, expect } from '@playwright/test';
const component = () => <div></div>; const component = () => <div></div>;
test('succeeds', () => { test('succeeds', () => {
expect(1 + 1).toBe(2); expect(1 + 1).toBe(2);
@ -525,14 +519,14 @@ test('should load a jsx/tsx files with fragments', async ({ runInlineTest }) =>
`, `,
'a.spec.ts': ` 'a.spec.ts': `
import { add } from './helper'; import { add } from './helper';
const { test } = pwt; import { test, expect } from '@playwright/test';
test('succeeds', () => { test('succeeds', () => {
expect(add(1, 1)).toBe(2); expect(add(1, 1)).toBe(2);
}); });
`, `,
'b.spec.js': ` 'b.spec.js': `
const { add } = require('./helper2'); const { add } = require('./helper2');
const { test } = pwt; import { test, expect } from '@playwright/test';
test('succeeds', () => { test('succeeds', () => {
expect(add(1, 1)).toBe(2); expect(add(1, 1)).toBe(2);
}); });
@ -548,7 +542,7 @@ test('should remove type imports from ts', async ({ runInlineTest }) => {
import { Point } from 'helper'; import { Point } from 'helper';
const p: Point = {}; const p: Point = {};
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
`, `,
'node_modules/helper/index.d.ts': ` 'node_modules/helper/index.d.ts': `
@ -562,7 +556,7 @@ test('should remove type imports from ts', async ({ runInlineTest }) => {
test('should resolve .js import to .ts file in non-ESM mode', async ({ runInlineTest }) => { test('should resolve .js import to .ts file in non-ESM mode', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
import { gimmeAOne } from './playwright-utils.js'; import { gimmeAOne } from './playwright-utils.js';
test('pass', ({}) => { test('pass', ({}) => {
expect(gimmeAOne()).toBe(1); expect(gimmeAOne()).toBe(1);
@ -581,7 +575,7 @@ test('should resolve .js import to .ts file in non-ESM mode', async ({ runInline
test('should resolve .js import to .tsx file in non-ESM mode', async ({ runInlineTest }) => { test('should resolve .js import to .tsx file in non-ESM mode', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
import { gimmeAOne } from './playwright-utils.js'; import { gimmeAOne } from './playwright-utils.js';
test('pass', ({}) => { test('pass', ({}) => {
expect(gimmeAOne()).toBe(1); expect(gimmeAOne()).toBe(1);
@ -611,7 +605,6 @@ test('should resolve .js import to .tsx file in non-ESM mode for components', as
`, `,
'src/test.spec.tsx': ` 'src/test.spec.tsx': `
//@no-header
import { test, expect } from '@playwright/experimental-ct-react'; import { test, expect } from '@playwright/experimental-ct-react';
import { Button } from './button.js'; import { Button } from './button.js';
test('pass', async ({ mount }) => { test('pass', async ({ mount }) => {
@ -626,7 +619,7 @@ test('should resolve .js import to .tsx file in non-ESM mode for components', as
test('should import export assignment from ts', async ({ runInlineTest }) => { test('should import export assignment from ts', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
import number from './utils.js'; import number from './utils.js';
test('pass', () => { test('pass', () => {
expect(number).toBe(1); expect(number).toBe(1);

View File

@ -18,7 +18,7 @@ import { test, expect } from './playwright-test-fixtures';
const files = { const files = {
'match-grep/b.test.ts': ` 'match-grep/b.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test AA', () => { test('test AA', () => {
expect(1 + 1).toBe(2); expect(1 + 1).toBe(2);
}); });
@ -32,7 +32,7 @@ const files = {
}); });
`, `,
'match-grep/fdir/c.test.ts': ` 'match-grep/fdir/c.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test AA', () => { test('test AA', () => {
expect(1 + 1).toBe(2); expect(1 + 1).toBe(2);
}); });
@ -46,7 +46,7 @@ const files = {
}); });
`, `,
'match-grep/adir/a.test.ts': ` 'match-grep/adir/a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test AA', () => { test('test AA', () => {
expect(1 + 1).toBe(2); expect(1 + 1).toBe(2);
}); });

View File

@ -19,7 +19,7 @@ import { test, expect } from './playwright-test-fixtures';
test('max-failures should work', async ({ runInlineTest }) => { test('max-failures should work', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.js': ` 'a.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
for (let i = 0; i < 10; ++i) { for (let i = 0; i < 10; ++i) {
test('fail_' + i, () => { test('fail_' + i, () => {
expect(true).toBe(false); expect(true).toBe(false);
@ -27,7 +27,7 @@ test('max-failures should work', async ({ runInlineTest }) => {
} }
`, `,
'b.spec.js': ` 'b.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
for (let i = 0; i < 10; ++i) { for (let i = 0; i < 10; ++i) {
test('fail_' + i, () => { test('fail_' + i, () => {
expect(true).toBe(false); expect(true).toBe(false);
@ -45,7 +45,7 @@ test('max-failures should work', async ({ runInlineTest }) => {
test('-x should work', async ({ runInlineTest }) => { test('-x should work', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.js': ` 'a.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
for (let i = 0; i < 10; ++i) { for (let i = 0; i < 10; ++i) {
test('fail_' + i, () => { test('fail_' + i, () => {
expect(true).toBe(false); expect(true).toBe(false);
@ -53,7 +53,7 @@ test('-x should work', async ({ runInlineTest }) => {
} }
`, `,
'b.spec.js': ` 'b.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
for (let i = 0; i < 10; ++i) { for (let i = 0; i < 10; ++i) {
test('fail_' + i, () => { test('fail_' + i, () => {
expect(true).toBe(false); expect(true).toBe(false);
@ -69,7 +69,7 @@ test('-x should work', async ({ runInlineTest }) => {
test('max-failures should work with retries', async ({ runInlineTest }) => { test('max-failures should work with retries', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.js': ` 'a.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
for (let i = 0; i < 10; ++i) { for (let i = 0; i < 10; ++i) {
test('fail_' + i, () => { test('fail_' + i, () => {
expect(true).toBe(false); expect(true).toBe(false);
@ -85,7 +85,7 @@ test('max-failures should work with retries', async ({ runInlineTest }) => {
test('max-failures should stop workers', async ({ runInlineTest }) => { test('max-failures should stop workers', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.js': ` 'a.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('passed', async () => { test('passed', async () => {
await new Promise(f => setTimeout(f, 2000)); await new Promise(f => setTimeout(f, 2000));
}); });
@ -94,7 +94,7 @@ test('max-failures should stop workers', async ({ runInlineTest }) => {
}); });
`, `,
'b.spec.js': ` 'b.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('passed short', async () => { test('passed short', async () => {
await new Promise(f => setTimeout(f, 1)); await new Promise(f => setTimeout(f, 1));
}); });
@ -126,7 +126,7 @@ test('max-failures should properly shutdown', async ({ runInlineTest }) => {
export default config; export default config;
`, `,
'test1.spec.ts': ` 'test1.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.describe('spec 1', () => { test.describe('spec 1', () => {
test('test 1', async () => { test('test 1', async () => {
expect(false).toBeTruthy() expect(false).toBeTruthy()
@ -134,7 +134,7 @@ test('max-failures should properly shutdown', async ({ runInlineTest }) => {
}); });
`, `,
'test2.spec.ts': ` 'test2.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.describe('spec 2', () => { test.describe('spec 2', () => {
test('test 2', () => { test('test 2', () => {
expect(true).toBeTruthy() expect(true).toBeTruthy()

View File

@ -22,7 +22,7 @@ test('should consider dynamically set value', async ({ runInlineTest }) => {
module.exports = { timeout: 2000 }; module.exports = { timeout: 2000 };
`, `,
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}, testInfo) => { test('pass', ({}, testInfo) => {
expect(testInfo.timeout).toBe(2000); expect(testInfo.timeout).toBe(2000);
}) })
@ -41,7 +41,7 @@ test('should allow different timeouts', async ({ runInlineTest }) => {
] }; ] };
`, `,
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}, testInfo) => { test('pass', ({}, testInfo) => {
console.log('timeout:' + testInfo.timeout); console.log('timeout:' + testInfo.timeout);
}); });
@ -59,7 +59,7 @@ test('should prioritize value set via command line', async ({ runInlineTest }) =
module.exports = { timeout: 2000 }; module.exports = { timeout: 2000 };
`, `,
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}, testInfo) => { test('pass', ({}, testInfo) => {
expect(testInfo.timeout).toBe(1000); expect(testInfo.timeout).toBe(1000);
}) })

View File

@ -60,16 +60,6 @@ type Params = { [key: string]: string | number | boolean | string[] };
async function writeFiles(testInfo: TestInfo, files: Files, initial: boolean) { async function writeFiles(testInfo: TestInfo, files: Files, initial: boolean) {
const baseDir = testInfo.outputPath(); const baseDir = testInfo.outputPath();
const headerJS = `
const pwt = require('@playwright/test');
`;
const headerTS = `
import * as pwt from '@playwright/test';
`;
const headerESM = `
import * as pwt from '@playwright/test';
`;
const hasConfig = Object.keys(files).some(name => name.includes('.config.')); const hasConfig = Object.keys(files).some(name => name.includes('.config.'));
if (initial && !hasConfig) { if (initial && !hasConfig) {
files = { files = {
@ -89,19 +79,7 @@ async function writeFiles(testInfo: TestInfo, files: Files, initial: boolean) {
await Promise.all(Object.keys(files).map(async name => { await Promise.all(Object.keys(files).map(async name => {
const fullName = path.join(baseDir, name); const fullName = path.join(baseDir, name);
await fs.promises.mkdir(path.dirname(fullName), { recursive: true }); await fs.promises.mkdir(path.dirname(fullName), { recursive: true });
const isTypeScriptSourceFile = name.endsWith('.ts') && !name.endsWith('.d.ts');
const isJSModule = name.endsWith('.mjs') || name.includes('esm');
const header = isTypeScriptSourceFile ? headerTS : (isJSModule ? headerESM : headerJS);
if (typeof files[name] === 'string' && files[name].includes('//@no-header')) {
await fs.promises.writeFile(fullName, files[name]); await fs.promises.writeFile(fullName, files[name]);
} else if (/(spec|test)\.(js|ts|jsx|tsx|mjs)$/.test(name)) {
const fileHeader = header + 'const { expect } = pwt;\n';
await fs.promises.writeFile(fullName, fileHeader + files[name]);
} else if (/\.(js|ts)$/.test(name) && !name.endsWith('d.ts')) {
await fs.promises.writeFile(fullName, header + files[name]);
} else {
await fs.promises.writeFile(fullName, files[name]);
}
})); }));
return baseDir; return baseDir;
@ -213,7 +191,6 @@ function watchPlaywrightTest(childProcess: CommonFixtures['childProcess'], baseD
async function runPlaywrightCommand(childProcess: CommonFixtures['childProcess'], cwd: string, commandWithArguments: string[], env: NodeJS.ProcessEnv, sendSIGINTAfter?: number): Promise<CliRunResult> { async function runPlaywrightCommand(childProcess: CommonFixtures['childProcess'], cwd: string, commandWithArguments: string[], env: NodeJS.ProcessEnv, sendSIGINTAfter?: number): Promise<CliRunResult> {
const command = ['node', cliEntrypoint]; const command = ['node', cliEntrypoint];
command.push(...commandWithArguments); command.push(...commandWithArguments);
const cacheDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'playwright-test-cache-'));
const testProcess = childProcess({ const testProcess = childProcess({
command, command,
env: cleanEnv(env), env: cleanEnv(env),
@ -227,7 +204,6 @@ async function runPlaywrightCommand(childProcess: CommonFixtures['childProcess']
} }
}; };
const { exitCode } = await testProcess.exited; const { exitCode } = await testProcess.exited;
await removeFolderAsync(cacheDir);
return { exitCode, output: testProcess.output.toString() }; return { exitCode, output: testProcess.output.toString() };
} }

View File

@ -36,7 +36,7 @@ const testFiles = {
import path from 'path'; import path from 'path';
import rimraf from 'rimraf'; import rimraf from 'rimraf';
const { test } = pwt; import { test, expect } from '@playwright/test';
test.describe('shared', () => { test.describe('shared', () => {
let page; let page;
@ -192,7 +192,7 @@ test('should work with screenshot: only-on-failure', async ({ runInlineTest }, t
test('should work with screenshot: only-on-failure & fullPage', async ({ runInlineTest, server }, testInfo) => { test('should work with screenshot: only-on-failure & fullPage', async ({ runInlineTest, server }, testInfo) => {
const result = await runInlineTest({ const result = await runInlineTest({
'artifacts.spec.ts': ` 'artifacts.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('should fail and take fullPage screenshots', async ({ page }) => { test('should fail and take fullPage screenshots', async ({ page }) => {
await page.setViewportSize({ width: 500, height: 500 }); await page.setViewportSize({ width: 500, height: 500 });
@ -316,7 +316,7 @@ test('should take screenshot when page is closed in afterEach', async ({ runInli
module.exports = { use: { screenshot: 'on' } }; module.exports = { use: { screenshot: 'on' } };
`, `,
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.afterEach(async ({ page }) => { test.afterEach(async ({ page }) => {
await page.close(); await page.close();

View File

@ -29,7 +29,7 @@ test('should fall back to launchOptions', async ({ runInlineTest }) => {
}; };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async ({ headless, channel }) => { test('pass', async ({ headless, channel }) => {
expect.soft(headless).toBe(false); expect.soft(headless).toBe(false);
expect.soft(channel).toBe('chrome'); expect.soft(channel).toBe('chrome');
@ -56,7 +56,7 @@ test('should override launchOptions', async ({ runInlineTest }) => {
}; };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async ({ headless, channel }) => { test('pass', async ({ headless, channel }) => {
expect.soft(headless).toBe(false); expect.soft(headless).toBe(false);
expect.soft(channel).toBe('chrome'); expect.soft(channel).toBe('chrome');
@ -94,7 +94,7 @@ test('should respect contextOptions', async ({ runInlineTest }) => {
}; };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async ({ acceptDownloads, bypassCSP, colorScheme, deviceScaleFactor, extraHTTPHeaders, hasTouch, ignoreHTTPSErrors, isMobile, javaScriptEnabled, locale, offline, permissions, timezoneId, userAgent, viewport }) => { test('pass', async ({ acceptDownloads, bypassCSP, colorScheme, deviceScaleFactor, extraHTTPHeaders, hasTouch, ignoreHTTPSErrors, isMobile, javaScriptEnabled, locale, offline, permissions, timezoneId, userAgent, viewport }) => {
expect.soft(acceptDownloads).toBe(false); expect.soft(acceptDownloads).toBe(false);
expect.soft(bypassCSP).toBe(true); expect.soft(bypassCSP).toBe(true);
@ -160,7 +160,7 @@ test('should override contextOptions', async ({ runInlineTest }) => {
}; };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async ({ acceptDownloads, bypassCSP, colorScheme, deviceScaleFactor, extraHTTPHeaders, hasTouch, ignoreHTTPSErrors, isMobile, javaScriptEnabled, locale, offline, permissions, timezoneId, userAgent, viewport }) => { test('pass', async ({ acceptDownloads, bypassCSP, colorScheme, deviceScaleFactor, extraHTTPHeaders, hasTouch, ignoreHTTPSErrors, isMobile, javaScriptEnabled, locale, offline, permissions, timezoneId, userAgent, viewport }) => {
expect.soft(acceptDownloads).toBe(false); expect.soft(acceptDownloads).toBe(false);
expect.soft(bypassCSP).toBe(true); expect.soft(bypassCSP).toBe(true);
@ -195,7 +195,7 @@ test('should respect testIdAttribute', async ({ runInlineTest }) => {
}; };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async ({ page }) => { test('pass', async ({ page }) => {
await page.setContent('<div data-pw="myid">Hi</div>'); await page.setContent('<div data-pw="myid">Hi</div>');
await expect(page.getByTestId('myid')).toHaveCount(1); await expect(page.getByTestId('myid')).toHaveCount(1);

View File

@ -29,14 +29,15 @@ test('should work with connectOptions', async ({ runInlineTest }) => {
}; };
`, `,
'global-setup.ts': ` 'global-setup.ts': `
import { chromium } from '@playwright/test';
module.exports = async () => { module.exports = async () => {
const server = await pwt.chromium.launchServer(); const server = await chromium.launchServer();
process.env.CONNECT_WS_ENDPOINT = server.wsEndpoint(); process.env.CONNECT_WS_ENDPOINT = server.wsEndpoint();
return () => server.close(); return () => server.close();
}; };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.use({ locale: 'fr-CH' }); test.use({ locale: 'fr-CH' });
test('pass', async ({ page }) => { test('pass', async ({ page }) => {
await page.setContent('<div>PASS</div>'); await page.setContent('<div>PASS</div>');
@ -61,7 +62,7 @@ test('should throw with bad connectOptions', async ({ runInlineTest }) => {
}; };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async ({ page }) => { test('pass', async ({ page }) => {
await page.setContent('<div>PASS</div>'); await page.setContent('<div>PASS</div>');
await expect(page.locator('div')).toHaveText('PASS'); await expect(page.locator('div')).toHaveText('PASS');
@ -87,7 +88,7 @@ test('should respect connectOptions.timeout', async ({ runInlineTest }) => {
}; };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async ({ page }) => { test('pass', async ({ page }) => {
}); });
`, `,

View File

@ -31,7 +31,6 @@ test('should work with the empty component list', async ({ runInlineTest }, test
'playwright/index.js': ``, 'playwright/index.js': ``,
'a.test.ts': ` 'a.test.ts': `
//@no-header
import { test, expect } from '@playwright/experimental-ct-react'; import { test, expect } from '@playwright/experimental-ct-react';
test('pass', async ({ mount }) => {}); test('pass', async ({ mount }) => {});
`, `,
@ -77,7 +76,6 @@ test('should extract component list', async ({ runInlineTest }, testInfo) => {
`, `,
'src/one-import.spec.tsx': ` 'src/one-import.spec.tsx': `
//@no-header
import { test, expect } from '@playwright/experimental-ct-react'; import { test, expect } from '@playwright/experimental-ct-react';
import { Button } from './button'; import { Button } from './button';
test('pass', async ({ mount }) => { test('pass', async ({ mount }) => {
@ -87,7 +85,6 @@ test('should extract component list', async ({ runInlineTest }, testInfo) => {
`, `,
'src/named-imports.spec.tsx': ` 'src/named-imports.spec.tsx': `
//@no-header
import { test, expect } from '@playwright/experimental-ct-react'; import { test, expect } from '@playwright/experimental-ct-react';
import { Component1, Component2 } from './components'; import { Component1, Component2 } from './components';
@ -103,7 +100,6 @@ test('should extract component list', async ({ runInlineTest }, testInfo) => {
`, `,
'src/default-import.spec.tsx': ` 'src/default-import.spec.tsx': `
//@no-header
import { test, expect } from '@playwright/experimental-ct-react'; import { test, expect } from '@playwright/experimental-ct-react';
import DefaultComponent from './defaultExport'; import DefaultComponent from './defaultExport';
@ -114,7 +110,6 @@ test('should extract component list', async ({ runInlineTest }, testInfo) => {
`, `,
'src/clashing-imports.spec.tsx': ` 'src/clashing-imports.spec.tsx': `
//@no-header
import { test, expect } from '@playwright/experimental-ct-react'; import { test, expect } from '@playwright/experimental-ct-react';
import DefaultComponent from './defaultExport.tsx'; import DefaultComponent from './defaultExport.tsx';
@ -235,7 +230,6 @@ test('should cache build', async ({ runInlineTest }, testInfo) => {
`, `,
'src/button.test.tsx': ` 'src/button.test.tsx': `
//@no-header
import { test, expect } from '@playwright/experimental-ct-react'; import { test, expect } from '@playwright/experimental-ct-react';
import { Button } from './button.tsx'; import { Button } from './button.tsx';
@ -266,7 +260,6 @@ test('should cache build', async ({ runInlineTest }, testInfo) => {
const result = await runInlineTest({ const result = await runInlineTest({
'playwright.config.ts': playwrightConfig, 'playwright.config.ts': playwrightConfig,
'src/button.test.tsx': ` 'src/button.test.tsx': `
//@no-header
import { test, expect } from '@playwright/experimental-ct-react'; import { test, expect } from '@playwright/experimental-ct-react';
import { Button } from './button.tsx'; import { Button } from './button.tsx';
@ -311,7 +304,6 @@ test('should grow cache', async ({ runInlineTest }, testInfo) => {
export const Button2 = () => <button>Button 2</button>; export const Button2 = () => <button>Button 2</button>;
`, `,
'src/button1.test.tsx': ` 'src/button1.test.tsx': `
//@no-header
import { test, expect } from '@playwright/experimental-ct-react'; import { test, expect } from '@playwright/experimental-ct-react';
import { Button1 } from './button1.tsx'; import { Button1 } from './button1.tsx';
test('pass', async ({ mount }) => { test('pass', async ({ mount }) => {
@ -320,7 +312,6 @@ test('should grow cache', async ({ runInlineTest }, testInfo) => {
}); });
`, `,
'src/button2.test.tsx': ` 'src/button2.test.tsx': `
//@no-header
import { test, expect } from '@playwright/experimental-ct-react'; import { test, expect } from '@playwright/experimental-ct-react';
import { Button2 } from './button2.tsx'; import { Button2 } from './button2.tsx';
test('pass', async ({ mount }) => { test('pass', async ({ mount }) => {
@ -372,7 +363,6 @@ test('should not use global config for preview', async ({ runInlineTest }) => {
}; };
`, `,
'a.test.ts': ` 'a.test.ts': `
//@no-header
import { test, expect } from '@playwright/experimental-ct-react'; import { test, expect } from '@playwright/experimental-ct-react';
test('pass', async ({ mount }) => {}); test('pass', async ({ mount }) => {});
`, `,
@ -390,9 +380,8 @@ test('should not use global config for preview', async ({ runInlineTest }) => {
test('should work with https enabled', async ({ runInlineTest }) => { test('should work with https enabled', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'playwright/index.html': `<script type="module" src="./index.js"></script>`, 'playwright/index.html': `<script type="module" src="./index.js"></script>`,
'playwright/index.js': `//@no-header`, 'playwright/index.js': ``,
'playwright.config.js': ` 'playwright.config.js': `
//@no-header
import { defineConfig } from '@playwright/experimental-ct-react'; import { defineConfig } from '@playwright/experimental-ct-react';
import basicSsl from '@vitejs/plugin-basic-ssl'; import basicSsl from '@vitejs/plugin-basic-ssl';
export default defineConfig({ export default defineConfig({
@ -408,7 +397,6 @@ test('should work with https enabled', async ({ runInlineTest }) => {
}); });
`, `,
'http.test.tsx': ` 'http.test.tsx': `
//@no-header
import { test, expect } from '@playwright/experimental-ct-react'; import { test, expect } from '@playwright/experimental-ct-react';
test('pass', async ({ page }) => { test('pass', async ({ page }) => {

View File

@ -26,14 +26,11 @@ test('should work with TSX', async ({ runInlineTest }) => {
'playwright.config.ts': playwrightConfig, 'playwright.config.ts': playwrightConfig,
'playwright/index.html': `<script type="module" src="./index.ts"></script>`, 'playwright/index.html': `<script type="module" src="./index.ts"></script>`,
'playwright/index.ts': ` 'playwright/index.ts': `
//@no-header
`, `,
'src/button.tsx': ` 'src/button.tsx': `
//@no-header
export const Button = () => <button>Button</button>; export const Button = () => <button>Button</button>;
`, `,
'src/button.test.tsx': ` 'src/button.test.tsx': `
//@no-header
import { test, expect } from '@playwright/experimental-ct-react'; import { test, expect } from '@playwright/experimental-ct-react';
import { Button } from './button'; import { Button } from './button';
@ -53,16 +50,13 @@ test('should work with JSX', async ({ runInlineTest }) => {
'playwright.config.ts': playwrightConfig, 'playwright.config.ts': playwrightConfig,
'playwright/index.html': `<script type="module" src="./index.js"></script>`, 'playwright/index.html': `<script type="module" src="./index.js"></script>`,
'playwright/index.js': ` 'playwright/index.js': `
//@no-header
`, `,
'src/button.jsx': ` 'src/button.jsx': `
//@no-header
export const Button = () => <button>Button</button>; export const Button = () => <button>Button</button>;
`, `,
'src/button.test.jsx': ` 'src/button.test.jsx': `
//@no-header
import { test, expect } from '@playwright/experimental-ct-react'; import { test, expect } from '@playwright/experimental-ct-react';
import { Button } from './button'; import { Button } from './button';
@ -82,16 +76,13 @@ test('should work with JSX in JS', async ({ runInlineTest }) => {
'playwright.config.ts': playwrightConfig, 'playwright.config.ts': playwrightConfig,
'playwright/index.html': `<script type="module" src="./index.js"></script>`, 'playwright/index.html': `<script type="module" src="./index.js"></script>`,
'playwright/index.js': ` 'playwright/index.js': `
//@no-header
`, `,
'src/button.js': ` 'src/button.js': `
//@no-header
export const Button = () => <button>Button</button>; export const Button = () => <button>Button</button>;
`, `,
'src/button.test.jsx': ` 'src/button.test.jsx': `
//@no-header
import { test, expect } from '@playwright/experimental-ct-react'; import { test, expect } from '@playwright/experimental-ct-react';
import { Button } from './button'; import { Button } from './button';
@ -111,21 +102,17 @@ test('should work with JSX in JS and in JSX', async ({ runInlineTest }) => {
'playwright.config.ts': playwrightConfig, 'playwright.config.ts': playwrightConfig,
'playwright/index.html': `<script type="module" src="./index.js"></script>`, 'playwright/index.html': `<script type="module" src="./index.js"></script>`,
'playwright/index.js': ` 'playwright/index.js': `
//@no-header
`, `,
'src/button.js': ` 'src/button.js': `
//@no-header
export const Button = () => <button>Button</button>; export const Button = () => <button>Button</button>;
`, `,
'src/list.jsx': ` 'src/list.jsx': `
//@no-header
export const List = () => <ul><li>List</li></ul>; export const List = () => <ul><li>List</li></ul>;
`, `,
'src/button.test.jsx': ` 'src/button.test.jsx': `
//@no-header
import { test, expect } from '@playwright/experimental-ct-react'; import { test, expect } from '@playwright/experimental-ct-react';
import { Button } from './button'; import { Button } from './button';
import { List } from './list'; import { List } from './list';
@ -152,21 +139,17 @@ test('should work with stray TSX import', async ({ runInlineTest }) => {
'playwright.config.ts': playwrightConfig, 'playwright.config.ts': playwrightConfig,
'playwright/index.html': `<script type="module" src="./index.ts"></script>`, 'playwright/index.html': `<script type="module" src="./index.ts"></script>`,
'playwright/index.ts': ` 'playwright/index.ts': `
//@no-header
`, `,
'src/button.tsx': ` 'src/button.tsx': `
//@no-header
export const Button = () => <button>Button</button>; export const Button = () => <button>Button</button>;
`, `,
'src/list.tsx': ` 'src/list.tsx': `
//@no-header
export const List = () => <ul><li>List</li></ul>; export const List = () => <ul><li>List</li></ul>;
`, `,
'src/button.test.tsx': ` 'src/button.test.tsx': `
//@no-header
import { test, expect } from '@playwright/experimental-ct-react'; import { test, expect } from '@playwright/experimental-ct-react';
import { Button } from './button'; import { Button } from './button';
import { List } from './list'; import { List } from './list';
@ -187,21 +170,17 @@ test('should work with stray JSX import', async ({ runInlineTest }) => {
'playwright.config.ts': playwrightConfig, 'playwright.config.ts': playwrightConfig,
'playwright/index.html': `<script type="module" src="./index.js"></script>`, 'playwright/index.html': `<script type="module" src="./index.js"></script>`,
'playwright/index.js': ` 'playwright/index.js': `
//@no-header
`, `,
'src/button.jsx': ` 'src/button.jsx': `
//@no-header
export const Button = () => <button>Button</button>; export const Button = () => <button>Button</button>;
`, `,
'src/list.jsx': ` 'src/list.jsx': `
//@no-header
export const List = () => <ul><li>List</li></ul>; export const List = () => <ul><li>List</li></ul>;
`, `,
'src/button.test.jsx': ` 'src/button.test.jsx': `
//@no-header
import { test, expect } from '@playwright/experimental-ct-react'; import { test, expect } from '@playwright/experimental-ct-react';
import { Button } from './button'; import { Button } from './button';
import { List } from './list'; import { List } from './list';
@ -222,21 +201,17 @@ test.fixme('should work with stray JS import', async ({ runInlineTest }) => {
'playwright.config.ts': playwrightConfig, 'playwright.config.ts': playwrightConfig,
'playwright/index.html': `<script type="module" src="./index.js"></script>`, 'playwright/index.html': `<script type="module" src="./index.js"></script>`,
'playwright/index.js': ` 'playwright/index.js': `
//@no-header
`, `,
'src/button.js': ` 'src/button.js': `
//@no-header
export const Button = () => <button>Button</button>; export const Button = () => <button>Button</button>;
`, `,
'src/list.js': ` 'src/list.js': `
//@no-header
export const List = () => <ul><li>List</li></ul>; export const List = () => <ul><li>List</li></ul>;
`, `,
'src/button.test.jsx': ` 'src/button.test.jsx': `
//@no-header
import { test, expect } from '@playwright/experimental-ct-react'; import { test, expect } from '@playwright/experimental-ct-react';
import { Button } from './button'; import { Button } from './button';
import { List } from './list'; import { List } from './list';
@ -257,16 +232,13 @@ test('should work with JSX in variable', async ({ runInlineTest }) => {
'playwright.config.ts': playwrightConfig, 'playwright.config.ts': playwrightConfig,
'playwright/index.html': `<script type="module" src="./index.js"></script>`, 'playwright/index.html': `<script type="module" src="./index.js"></script>`,
'playwright/index.js': ` 'playwright/index.js': `
//@no-header
`, `,
'src/button.jsx': ` 'src/button.jsx': `
//@no-header
export const Button = () => <button>Button</button>; export const Button = () => <button>Button</button>;
`, `,
'src/button.test.jsx': ` 'src/button.test.jsx': `
//@no-header
import { test, expect } from '@playwright/experimental-ct-react'; import { test, expect } from '@playwright/experimental-ct-react';
import { Button } from './button'; import { Button } from './button';
@ -287,15 +259,13 @@ test('should return root locator for fragments', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'playwright.config.ts': playwrightConfig, 'playwright.config.ts': playwrightConfig,
'playwright/index.html': `<script type="module" src="./index.js"></script>`, 'playwright/index.html': `<script type="module" src="./index.js"></script>`,
'playwright/index.js': `//@no-header`, 'playwright/index.js': ``,
'src/button.jsx': ` 'src/button.jsx': `
//@no-header
export const Button = () => <><h1>Header</h1><button>Button</button></>; export const Button = () => <><h1>Header</h1><button>Button</button></>;
`, `,
'src/button.test.jsx': ` 'src/button.test.jsx': `
//@no-header
import { test, expect } from '@playwright/experimental-ct-react'; import { test, expect } from '@playwright/experimental-ct-react';
import { Button } from './button'; import { Button } from './button';
@ -315,13 +285,12 @@ test('should respect default property values', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'playwright.config.ts': playwrightConfig, 'playwright.config.ts': playwrightConfig,
'playwright/index.html': `<script type="module" src="./index.ts"></script>`, 'playwright/index.html': `<script type="module" src="./index.ts"></script>`,
'playwright/index.ts': `//@no-header`, 'playwright/index.ts': ``,
'src/label.tsx': `//@no-header 'src/label.tsx': `
export const Label = ({ checked }) => <div>type:{typeof checked} value:{String(checked)}</div>; export const Label = ({ checked }) => <div>type:{typeof checked} value:{String(checked)}</div>;
`, `,
'src/label.test.tsx': ` 'src/label.test.tsx': `
//@no-header
import { test, expect } from '@playwright/experimental-ct-react'; import { test, expect } from '@playwright/experimental-ct-react';
import { Label } from './label'; import { Label } from './label';
@ -341,19 +310,15 @@ test('should bundle public folder', async ({ runInlineTest }) => {
'playwright.config.ts': playwrightConfig, 'playwright.config.ts': playwrightConfig,
'playwright/index.html': `<script type="module" src="./index.ts"></script>`, 'playwright/index.html': `<script type="module" src="./index.ts"></script>`,
'playwright/index.ts': ` 'playwright/index.ts': `
//@no-header
`, `,
'public/logo.svg': ` 'public/logo.svg': `
//@no-header
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"> <svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="50"/> <circle cx="50" cy="50" r="50"/>
</svg>`, </svg>`,
'src/image.tsx': ` 'src/image.tsx': `
//@no-header
export const Image = () => <img src='/logo.svg' className="App-logo" alt="logo" />; export const Image = () => <img src='/logo.svg' className="App-logo" alt="logo" />;
`, `,
'src/image.test.tsx': ` 'src/image.test.tsx': `
//@no-header
import { test, expect } from '@playwright/experimental-ct-react'; import { test, expect } from '@playwright/experimental-ct-react';
import { Image } from './image'; import { Image } from './image';

View File

@ -19,7 +19,7 @@ import { test, expect } from './playwright-test-fixtures';
test('should expose request fixture', async ({ runInlineTest, server }) => { test('should expose request fixture', async ({ runInlineTest, server }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async ({ request }) => { test('pass', async ({ request }) => {
const response = await request.get('${server.PREFIX}/simple.json'); const response = await request.get('${server.PREFIX}/simple.json');
const json = await response.json(); const json = await response.json();
@ -38,7 +38,7 @@ test('should use baseURL in request fixture', async ({ runInlineTest, server })
module.exports = { use: { baseURL: '${server.PREFIX}' } }; module.exports = { use: { baseURL: '${server.PREFIX}' } };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async ({ request }) => { test('pass', async ({ request }) => {
const response = await request.get('/simple.json'); const response = await request.get('/simple.json');
const json = await response.json(); const json = await response.json();
@ -72,7 +72,7 @@ test('should stop tracing on requestContex.dispose()', async ({ runInlineTest, s
}; };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('hanging request', async ({ page, request }) => { test('hanging request', async ({ page, request }) => {
const response = await page.goto('${server.EMPTY_PAGE}'); const response = await page.goto('${server.EMPTY_PAGE}');
expect(response.status()).toBe(200); expect(response.status()).toBe(200);

View File

@ -21,7 +21,7 @@ import fs from 'fs';
test('should reuse context', async ({ runInlineTest }) => { test('should reuse context', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'src/reuse.test.ts': ` 'src/reuse.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
let lastContextGuid; let lastContextGuid;
test('one', async ({ context }) => { test('one', async ({ context }) => {
lastContextGuid = context._guid; lastContextGuid = context._guid;
@ -66,7 +66,7 @@ test('should not reuse context with video if mode=when-possible', async ({ runIn
}; };
`, `,
'src/reuse.test.ts': ` 'src/reuse.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
let lastContextGuid; let lastContextGuid;
test('one', async ({ context }) => { test('one', async ({ context }) => {
@ -93,7 +93,7 @@ test('should reuse context and disable video if mode=force', async ({ runInlineT
}; };
`, `,
'reuse.test.ts': ` 'reuse.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
let lastContextGuid; let lastContextGuid;
test('one', async ({ context, page }) => { test('one', async ({ context, page }) => {
@ -122,7 +122,7 @@ test('should reuse context with trace if mode=when-possible', async ({ runInline
}; };
`, `,
'reuse.spec.ts': ` 'reuse.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
let lastContextGuid; let lastContextGuid;
test('one', async ({ context, page }) => { test('one', async ({ context, page }) => {
@ -165,7 +165,7 @@ test('should reuse context with trace if mode=when-possible', async ({ runInline
test('should work with manually closed pages', async ({ runInlineTest }) => { test('should work with manually closed pages', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'src/button.test.ts': ` 'src/button.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('closes page', async ({ page }) => { test('closes page', async ({ page }) => {
await page.close(); await page.close();
@ -194,7 +194,7 @@ test('should work with manually closed pages', async ({ runInlineTest }) => {
test('should clean storage', async ({ runInlineTest }) => { test('should clean storage', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'src/reuse.test.ts': ` 'src/reuse.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
let lastContextGuid; let lastContextGuid;
test.beforeEach(async ({ page }) => { test.beforeEach(async ({ page }) => {
@ -237,7 +237,7 @@ test('should clean storage', async ({ runInlineTest }) => {
test('should restore localStorage', async ({ runInlineTest }) => { test('should restore localStorage', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'src/reuse.test.ts': ` 'src/reuse.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
let lastContextGuid; let lastContextGuid;
test.use({ test.use({
@ -312,7 +312,7 @@ test('should clean db', async ({ runInlineTest }) => {
test.slow(); test.slow();
const result = await runInlineTest({ const result = await runInlineTest({
'src/reuse.test.ts': ` 'src/reuse.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
let lastContextGuid; let lastContextGuid;
test.beforeEach(async ({ page }) => { test.beforeEach(async ({ page }) => {
@ -351,7 +351,7 @@ test('should clean db', async ({ runInlineTest }) => {
test('should restore cookies', async ({ runInlineTest }) => { test('should restore cookies', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'src/reuse.test.ts': ` 'src/reuse.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
let lastContextGuid; let lastContextGuid;
test.use({ test.use({
@ -409,7 +409,7 @@ test('should restore cookies', async ({ runInlineTest }) => {
test('should reuse context with beforeunload', async ({ runInlineTest }) => { test('should reuse context with beforeunload', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'src/reuse.test.ts': ` 'src/reuse.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
let lastContextGuid; let lastContextGuid;
test('one', async ({ page, context }) => { test('one', async ({ page, context }) => {
lastContextGuid = context._guid; lastContextGuid = context._guid;
@ -434,7 +434,7 @@ test('should reuse context with beforeunload', async ({ runInlineTest }) => {
test('should cancel pending operations upon reuse', async ({ runInlineTest }) => { test('should cancel pending operations upon reuse', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'src/reuse.test.ts': ` 'src/reuse.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('one', async ({ page }) => { test('one', async ({ page }) => {
await Promise.race([ await Promise.race([
page.getByText('click me').click().catch(e => {}), page.getByText('click me').click().catch(e => {}),
@ -460,7 +460,7 @@ test('should reset tracing', async ({ runInlineTest }, testInfo) => {
const traceFile2 = testInfo.outputPath('trace2.zip'); const traceFile2 = testInfo.outputPath('trace2.zip');
const result = await runInlineTest({ const result = await runInlineTest({
'reuse.spec.ts': ` 'reuse.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('one', async ({ page }) => { test('one', async ({ page }) => {
await page.context().tracing.start({ snapshots: true }); await page.context().tracing.start({ snapshots: true });
await page.setContent('<button>Click</button>'); await page.setContent('<button>Click</button>');
@ -499,7 +499,8 @@ test('should reset tracing', async ({ runInlineTest }, testInfo) => {
test('should not delete others contexts', async ({ runInlineTest }) => { test('should not delete others contexts', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'src/reuse.test.ts': ` 'src/reuse.test.ts': `
const test = pwt.test.extend<{ loggedInPage: Page }>({ import { test as base, expect } from '@playwright/test';
const test = base.extend<{ loggedInPage: Page }>({
loggedInPage: async ({ browser }, use) => { loggedInPage: async ({ browser }, use) => {
const page = await browser.newPage(); const page = await browser.newPage();
await use(page); await use(page);

View File

@ -42,13 +42,13 @@ test('should respect viewport option', async ({ runInlineTest }) => {
module.exports = { use: { viewport: { width: 800, height: 800 } } }; module.exports = { use: { viewport: { width: 800, height: 800 } } };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async ({ page }) => { test('pass', async ({ page }) => {
expect(page.viewportSize()).toEqual({ width: 800, height: 800 }); expect(page.viewportSize()).toEqual({ width: 800, height: 800 });
}); });
`, `,
'b.test.ts': ` 'b.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.use({ viewport: { width: 600, height: 600 } }); test.use({ viewport: { width: 600, height: 600 } });
test('pass', async ({ page }) => { test('pass', async ({ page }) => {
expect(page.viewportSize()).toEqual({ width: 600, height: 600 }); expect(page.viewportSize()).toEqual({ width: 600, height: 600 });
@ -66,7 +66,7 @@ test('should run in three browsers with --browser', async ({ runInlineTest }) =>
module.exports = { use: { viewport: { width: 800, height: 800 } } }; module.exports = { use: { viewport: { width: 800, height: 800 } } };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async ({ browserName }) => { test('pass', async ({ browserName }) => {
console.log('\\n%%browser=' + browserName); console.log('\\n%%browser=' + browserName);
}); });
@ -88,7 +88,7 @@ test('should run in one browser with --browser', async ({ runInlineTest }) => {
module.exports = { use: { viewport: { width: 800, height: 800 } } }; module.exports = { use: { viewport: { width: 800, height: 800 } } };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async ({ browserName }) => { test('pass', async ({ browserName }) => {
console.log('\\n%%browser=' + browserName); console.log('\\n%%browser=' + browserName);
}); });
@ -108,7 +108,7 @@ test('should complain with projects and --browser', async ({ runInlineTest }) =>
module.exports = { projects: [ {} ] }; module.exports = { projects: [ {} ] };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async ({ page }) => { test('pass', async ({ page }) => {
}); });
`, `,
@ -127,7 +127,7 @@ test('should override any headless option with --headed', async ({ runInlineTest
] }; ] };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('example', async ({ page }) => { test('example', async ({ page }) => {
expect(await page.evaluate(() => navigator.userAgent)).not.toContain('Headless'); expect(await page.evaluate(() => navigator.userAgent)).not.toContain('Headless');
}); });
@ -144,7 +144,7 @@ test('should not override use:browserName without projects', async ({ runInlineT
module.exports = { use: { browserName: 'webkit' } }; module.exports = { use: { browserName: 'webkit' } };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async ({ browserName }) => { test('pass', async ({ browserName }) => {
console.log('\\n%%browser=' + browserName); console.log('\\n%%browser=' + browserName);
}); });
@ -164,7 +164,7 @@ test('should override use:browserName with --browser', async ({ runInlineTest })
module.exports = { use: { browserName: 'webkit' } }; module.exports = { use: { browserName: 'webkit' } };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async ({ browserName }) => { test('pass', async ({ browserName }) => {
console.log('\\n%%browser=' + browserName); console.log('\\n%%browser=' + browserName);
}); });
@ -189,7 +189,7 @@ test('should respect context options in various contexts', async ({ runInlineTes
import path from 'path'; import path from 'path';
import rimraf from 'rimraf'; import rimraf from 'rimraf';
const { test } = pwt; import { test, expect } from '@playwright/test';
test.use({ locale: 'fr-FR' }); test.use({ locale: 'fr-FR' });
let context; let context;
@ -257,7 +257,7 @@ test('should respect headless in launchPersistent', async ({ runInlineTest }) =>
import path from 'path'; import path from 'path';
import rimraf from 'rimraf'; import rimraf from 'rimraf';
const { test } = pwt; import { test, expect } from '@playwright/test';
test('persistent context', async ({ playwright, browserName }) => { test('persistent context', async ({ playwright, browserName }) => {
const dir = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'user-data-dir-')); const dir = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'user-data-dir-'));
@ -280,7 +280,7 @@ test('should respect headless in modifiers that run before tests', async ({ runI
module.exports = { use: { headless: false } }; module.exports = { use: { headless: false } };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.skip(({ browser }) => false); test.skip(({ browser }) => false);
@ -297,7 +297,7 @@ test('should respect headless in modifiers that run before tests', async ({ runI
test('should call logger from launchOptions config', async ({ runInlineTest }, testInfo) => { test('should call logger from launchOptions config', async ({ runInlineTest }, testInfo) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
const log = []; const log = [];
test.use({ test.use({
launchOptions: { launchOptions: {
@ -325,7 +325,7 @@ test('should call logger from launchOptions config', async ({ runInlineTest }, t
test('should report error and pending operations on timeout', async ({ runInlineTest }, testInfo) => { test('should report error and pending operations on timeout', async ({ runInlineTest }, testInfo) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('timedout', async ({ page }) => { test('timedout', async ({ page }) => {
await page.setContent('<div>Click me</div>'); await page.setContent('<div>Click me</div>');
await Promise.all([ await Promise.all([
@ -340,16 +340,16 @@ test('should report error and pending operations on timeout', async ({ runInline
expect(result.passed).toBe(0); expect(result.passed).toBe(0);
expect(result.failed).toBe(1); expect(result.failed).toBe(1);
expect(result.output).toContain('Pending operations:'); expect(result.output).toContain('Pending operations:');
expect(result.output).toContain('- locator.click at a.test.ts:9:37'); expect(result.output).toContain('- locator.click at a.test.ts:6:37');
expect(result.output).toContain('- locator.textContent at a.test.ts:10:42'); expect(result.output).toContain('- locator.textContent at a.test.ts:7:42');
expect(result.output).toContain('waiting for'); expect(result.output).toContain('waiting for');
expect(result.output).toContain(`10 | page.getByText('More missing').textContent(),`); expect(result.output).toContain(`7 | page.getByText('More missing').textContent(),`);
}); });
test('should report error on timeout with shared page', async ({ runInlineTest }, testInfo) => { test('should report error on timeout with shared page', async ({ runInlineTest }, testInfo) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
let page; let page;
test.beforeAll(async ({ browser }) => { test.beforeAll(async ({ browser }) => {
page = await browser.newPage(); page = await browser.newPage();
@ -367,13 +367,13 @@ test('should report error on timeout with shared page', async ({ runInlineTest }
expect(result.passed).toBe(1); expect(result.passed).toBe(1);
expect(result.failed).toBe(1); expect(result.failed).toBe(1);
expect(result.output).toContain('waiting for getByText(\'Missing\')'); expect(result.output).toContain('waiting for getByText(\'Missing\')');
expect(result.output).toContain(`14 | await page.getByText('Missing').click();`); expect(result.output).toContain(`11 | await page.getByText('Missing').click();`);
}); });
test('should report error from beforeAll timeout', async ({ runInlineTest }, testInfo) => { test('should report error from beforeAll timeout', async ({ runInlineTest }, testInfo) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.beforeAll(async ({ browser }) => { test.beforeAll(async ({ browser }) => {
const page = await browser.newPage(); const page = await browser.newPage();
await page.setContent('<div>Click me</div>'); await page.setContent('<div>Click me</div>');
@ -391,13 +391,13 @@ test('should report error from beforeAll timeout', async ({ runInlineTest }, tes
expect(result.failed).toBe(1); expect(result.failed).toBe(1);
expect(result.output).toContain('"beforeAll" hook timeout of 2000ms exceeded.'); expect(result.output).toContain('"beforeAll" hook timeout of 2000ms exceeded.');
expect(result.output).toContain('waiting for'); expect(result.output).toContain('waiting for');
expect(result.output).toContain(`11 | page.getByText('More missing').textContent(),`); expect(result.output).toContain(`8 | page.getByText('More missing').textContent(),`);
}); });
test('should not report waitForEventInfo as pending', async ({ runInlineTest }, testInfo) => { test('should not report waitForEventInfo as pending', async ({ runInlineTest }, testInfo) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('timedout', async ({ page }) => { test('timedout', async ({ page }) => {
await page.setContent('<div>Click me</div>'); await page.setContent('<div>Click me</div>');
await page.waitForLoadState('networkidle'); await page.waitForLoadState('networkidle');
@ -410,14 +410,14 @@ test('should not report waitForEventInfo as pending', async ({ runInlineTest },
expect(result.passed).toBe(0); expect(result.passed).toBe(0);
expect(result.failed).toBe(1); expect(result.failed).toBe(1);
expect(result.output).toContain('Pending operations:'); expect(result.output).toContain('Pending operations:');
expect(result.output).toContain('- page.click at a.test.ts:9:20'); expect(result.output).toContain('- page.click at a.test.ts:6:20');
expect(result.output).not.toContain('- page.waitForLoadState'); expect(result.output).not.toContain('- page.waitForLoadState');
}); });
test('should throw when using page in beforeAll', async ({ runInlineTest }, testInfo) => { test('should throw when using page in beforeAll', async ({ runInlineTest }, testInfo) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.beforeAll(() => {}); test.beforeAll(() => {});
test.beforeAll(async ({ page }) => { test.beforeAll(async ({ page }) => {
}); });
@ -436,7 +436,7 @@ test('should report click error on sigint', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('timedout', async ({ page }) => { test('timedout', async ({ page }) => {
await page.setContent('<div>Click me</div>'); await page.setContent('<div>Click me</div>');
const promise = page.click('text=Missing'); const promise = page.click('text=Missing');
@ -451,7 +451,7 @@ test('should report click error on sigint', async ({ runInlineTest }) => {
expect(result.passed).toBe(0); expect(result.passed).toBe(0);
expect(result.failed).toBe(0); expect(result.failed).toBe(0);
expect(result.interrupted).toBe(1); expect(result.interrupted).toBe(1);
expect(result.output).toContain(`8 | const promise = page.click('text=Missing');`); expect(result.output).toContain(`5 | const promise = page.click('text=Missing');`);
}); });
test('should work with video: retain-on-failure', async ({ runInlineTest }, testInfo) => { test('should work with video: retain-on-failure', async ({ runInlineTest }, testInfo) => {
@ -460,7 +460,7 @@ test('should work with video: retain-on-failure', async ({ runInlineTest }, test
module.exports = { use: { video: 'retain-on-failure' }, name: 'chromium' }; module.exports = { use: { video: 'retain-on-failure' }, name: 'chromium' };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async ({ page }) => { test('pass', async ({ page }) => {
await page.setContent('<div>PASS</div>'); await page.setContent('<div>PASS</div>');
await page.waitForTimeout(3000); await page.waitForTimeout(3000);
@ -492,7 +492,7 @@ test('should work with video: on-first-retry', async ({ runInlineTest }, testInf
module.exports = { use: { video: 'on-first-retry' }, retries: 1, name: 'chromium' }; module.exports = { use: { video: 'on-first-retry' }, retries: 1, name: 'chromium' };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async ({ page }) => { test('pass', async ({ page }) => {
await page.setContent('<div>PASS</div>'); await page.setContent('<div>PASS</div>');
await page.waitForTimeout(3000); await page.waitForTimeout(3000);
@ -538,7 +538,7 @@ test('should work with video size', async ({ runInlineTest }, testInfo) => {
}; };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async ({ page }) => { test('pass', async ({ page }) => {
await page.setContent('<div>PASS</div>'); await page.setContent('<div>PASS</div>');
await page.waitForTimeout(3000); await page.waitForTimeout(3000);
@ -566,7 +566,7 @@ test('should work with video.path() throwing', async ({ runInlineTest }, testInf
}; };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async ({ page }) => { test('pass', async ({ page }) => {
page.video().path = () => { throw new Error('No-no!'); }; page.video().path = () => { throw new Error('No-no!'); };
await page.setContent('<div>PASS</div>'); await page.setContent('<div>PASS</div>');
@ -587,7 +587,7 @@ test('should pass fixture defaults to tests', async ({ runInlineTest }) => {
module.exports = {}; module.exports = {};
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async ({ acceptDownloads, actionTimeout, headless, javaScriptEnabled, navigationTimeout }) => { test('pass', async ({ acceptDownloads, actionTimeout, headless, javaScriptEnabled, navigationTimeout }) => {
expect(acceptDownloads).toBe(true); expect(acceptDownloads).toBe(true);
expect(actionTimeout).toBe(0); expect(actionTimeout).toBe(0);
@ -641,7 +641,7 @@ test('should not throw with many fixtures set to undefined', async ({ runInlineT
} }; } };
`, `,
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.use({ test.use({
browserName: undefined, browserName: undefined,
headless: undefined, headless: undefined,
@ -690,7 +690,7 @@ test('should not throw with many fixtures set to undefined', async ({ runInlineT
test('should have strict types for options but allow use(undefined)', async ({ runTSC }) => { test('should have strict types for options but allow use(undefined)', async ({ runTSC }) => {
const result = await runTSC({ const result = await runTSC({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.use({ test.use({
headless: undefined, headless: undefined,
acceptDownloads: undefined, acceptDownloads: undefined,
@ -728,7 +728,7 @@ test('should have strict types for options but allow use(undefined)', async ({ r
test('should skip on mobile', async ({ runInlineTest }) => { test('should skip on mobile', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.describe(() => { test.describe(() => {
test.use({ isMobile: true }); test.use({ isMobile: true });

View File

@ -24,7 +24,7 @@ test('should stop tracing with trace: on-first-retry, when not retrying', async
module.exports = { use: { trace: 'on-first-retry' } }; module.exports = { use: { trace: 'on-first-retry' } };
`, `,
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.describe('shared', () => { test.describe('shared', () => {
let page; let page;
@ -60,7 +60,7 @@ test('should record api trace', async ({ runInlineTest, server }, testInfo) => {
module.exports = { use: { trace: 'on' } }; module.exports = { use: { trace: 'on' } };
`, `,
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async ({request, page}, testInfo) => { test('pass', async ({request, page}, testInfo) => {
await page.goto('about:blank'); await page.goto('about:blank');
@ -99,7 +99,7 @@ test('should not throw with trace: on-first-retry and two retries in the same wo
const files = {}; const files = {};
for (let i = 0; i < 6; i++) { for (let i = 0; i < 6; i++) {
files[`a${i}.spec.ts`] = ` files[`a${i}.spec.ts`] = `
import { test } from './helper'; import { test, expect } from './helper';
test('flaky', async ({ myContext }, testInfo) => { test('flaky', async ({ myContext }, testInfo) => {
await new Promise(f => setTimeout(f, 200 + Math.round(Math.random() * 1000))); await new Promise(f => setTimeout(f, 200 + Math.round(Math.random() * 1000)));
expect(testInfo.retry).toBe(1); expect(testInfo.retry).toBe(1);
@ -115,7 +115,8 @@ test('should not throw with trace: on-first-retry and two retries in the same wo
module.exports = { use: { trace: 'on-first-retry' } }; module.exports = { use: { trace: 'on-first-retry' } };
`, `,
'helper.ts': ` 'helper.ts': `
const { test: base } = pwt; import { test as base } from '@playwright/test';
export * from '@playwright/test';
export const test = base.extend({ export const test = base.extend({
myContext: [async ({ browser }, use) => { myContext: [async ({ browser }, use) => {
const c = await browser.newContext(); const c = await browser.newContext();
@ -141,7 +142,7 @@ test('should save sources when requested', async ({ runInlineTest }, testInfo) =
}; };
`, `,
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async ({ page }) => { test('pass', async ({ page }) => {
await page.evaluate(2 + 2); await page.evaluate(2 + 2);
}); });
@ -165,7 +166,7 @@ test('should not save sources when not requested', async ({ runInlineTest }, tes
}; };
`, `,
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async ({ page }) => { test('pass', async ({ page }) => {
await page.evaluate(2 + 2); await page.evaluate(2 + 2);
}); });
@ -182,7 +183,7 @@ test('should work in serial mode', async ({ runInlineTest }, testInfo) => {
module.exports = { use: { trace: 'retain-on-failure' } }; module.exports = { use: { trace: 'retain-on-failure' } };
`, `,
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.describe.serial('serial', () => { test.describe.serial('serial', () => {
let page; let page;
@ -217,7 +218,7 @@ test('should not override trace file in afterAll', async ({ runInlineTest, serve
module.exports = { use: { trace: 'retain-on-failure' } }; module.exports = { use: { trace: 'retain-on-failure' } };
`, `,
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test 1', async ({ page }) => { test('test 1', async ({ page }) => {
await page.goto('about:blank'); await page.goto('about:blank');
@ -247,13 +248,15 @@ test('should retain traces for interrupted tests', async ({ runInlineTest }, tes
module.exports = { use: { trace: 'retain-on-failure' }, maxFailures: 1 }; module.exports = { use: { trace: 'retain-on-failure' }, maxFailures: 1 };
`, `,
'a.spec.ts': ` 'a.spec.ts': `
pwt.test('test 1', async ({ page }) => { import { test, expect } from '@playwright/test';
test('test 1', async ({ page }) => {
await page.waitForTimeout(2000); await page.waitForTimeout(2000);
expect(1).toBe(2); expect(1).toBe(2);
}); });
`, `,
'b.spec.ts': ` 'b.spec.ts': `
pwt.test('test 2', async ({ page }) => { import { test, expect } from '@playwright/test';
test('test 2', async ({ page }) => {
await page.goto('about:blank'); await page.goto('about:blank');
await page.waitForTimeout(5000); await page.waitForTimeout(5000);
}); });
@ -270,7 +273,8 @@ test('should retain traces for interrupted tests', async ({ runInlineTest }, tes
test('should respect --trace', async ({ runInlineTest }, testInfo) => { test('should respect --trace', async ({ runInlineTest }, testInfo) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
pwt.test('test 1', async ({ page }) => { import { test, expect } from '@playwright/test';
test('test 1', async ({ page }) => {
await page.goto('about:blank'); await page.goto('about:blank');
}); });
`, `,

View File

@ -19,7 +19,7 @@ import { test, expect } from './playwright-test-fixtures';
test('should lead in uncaughtException when page.route raises', async ({ runInlineTest, server }) => { test('should lead in uncaughtException when page.route raises', async ({ runInlineTest, server }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('fail', async ({ page }) => { test('fail', async ({ page }) => {
test.fail(); test.fail();
await page.route('**/empty.html', route => { await page.route('**/empty.html', route => {
@ -36,7 +36,7 @@ test('should lead in uncaughtException when page.route raises', async ({ runInli
test('should lead in unhandledRejection when page.route raises', async ({ runInlineTest, server }) => { test('should lead in unhandledRejection when page.route raises', async ({ runInlineTest, server }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('fail', async ({ page }) => { test('fail', async ({ page }) => {
test.fail(); test.fail();
await page.route('**/empty.html', async route => { await page.route('**/empty.html', async route => {
@ -53,7 +53,7 @@ test('should lead in unhandledRejection when page.route raises', async ({ runInl
test('should lead in uncaughtException when context.route raises', async ({ runInlineTest, server }) => { test('should lead in uncaughtException when context.route raises', async ({ runInlineTest, server }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('fail', async ({ context, page }) => { test('fail', async ({ context, page }) => {
test.fail(); test.fail();
await context.route('**/empty.html', route => { await context.route('**/empty.html', route => {
@ -70,7 +70,7 @@ test('should lead in uncaughtException when context.route raises', async ({ runI
test('should lead in unhandledRejection when context.route raises', async ({ runInlineTest, server }) => { test('should lead in unhandledRejection when context.route raises', async ({ runInlineTest, server }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('fail', async ({ context, page }) => { test('fail', async ({ context, page }) => {
test.fail(); test.fail();
await context.route('**/empty.html', async route => { await context.route('**/empty.html', async route => {

View File

@ -19,7 +19,7 @@ import { test, expect } from './playwright-test-fixtures';
test('should repeat from command line', async ({ runInlineTest }) => { test('should repeat from command line', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.js': ` 'a.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test', ({}, testInfo) => { test('test', ({}, testInfo) => {
console.log('REPEAT ' + testInfo.repeatEachIndex); console.log('REPEAT ' + testInfo.repeatEachIndex);
expect(1).toBe(1); expect(1).toBe(1);
@ -43,7 +43,7 @@ test('should repeat based on config', async ({ runInlineTest }) => {
] }; ] };
`, `,
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('my test', ({}, testInfo) => {}); test('my test', ({}, testInfo) => {});
` `
}); });

View File

@ -19,8 +19,8 @@ import { test, expect } from './playwright-test-fixtures';
test('render text attachment', async ({ runInlineTest }) => { test('render text attachment', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('one', async ({}, testInfo) => { test('one', async ({}, testInfo) => {
testInfo.attachments.push({ testInfo.attachments.push({
name: 'attachment', name: 'attachment',
@ -40,8 +40,8 @@ test('render text attachment', async ({ runInlineTest }) => {
test('render screenshot attachment', async ({ runInlineTest }) => { test('render screenshot attachment', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('one', async ({}, testInfo) => { test('one', async ({}, testInfo) => {
testInfo.attachments.push({ testInfo.attachments.push({
name: 'screenshot', name: 'screenshot',
@ -61,8 +61,8 @@ test('render screenshot attachment', async ({ runInlineTest }) => {
test('render trace attachment', async ({ runInlineTest }) => { test('render trace attachment', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('one', async ({}, testInfo) => { test('one', async ({}, testInfo) => {
testInfo.attachments.push({ testInfo.attachments.push({
name: 'trace', name: 'trace',
@ -83,8 +83,8 @@ test('render trace attachment', async ({ runInlineTest }) => {
test(`testInfo.attach errors`, async ({ runInlineTest }) => { test(`testInfo.attach errors`, async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('fail1', async ({}, testInfo) => { test('fail1', async ({}, testInfo) => {
await testInfo.attach('name', { path: 'foo.txt' }); await testInfo.attach('name', { path: 'foo.txt' });
}); });
@ -106,8 +106,8 @@ test(`testInfo.attach errors`, async ({ runInlineTest }) => {
test(`testInfo.attach errors with empty path`, async ({ runInlineTest }) => { test(`testInfo.attach errors with empty path`, async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('fail', async ({}, testInfo) => { test('fail', async ({}, testInfo) => {
await testInfo.attach('name', { path: '' }); await testInfo.attach('name', { path: '' });
}); });
@ -119,8 +119,9 @@ test(`testInfo.attach errors with empty path`, async ({ runInlineTest }) => {
test(`testInfo.attach error in fixture`, async ({ runInlineTest }) => { test(`testInfo.attach error in fixture`, async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
fixture: async ({}, use, testInfo) => { fixture: async ({}, use, testInfo) => {
await use(); await use();
await testInfo.attach('name', { path: 'foo.txt' }); await testInfo.attach('name', { path: 'foo.txt' });
@ -139,8 +140,9 @@ test(`testInfo.attach error in fixture`, async ({ runInlineTest }) => {
test(`testInfo.attach success in fixture`, async ({ runInlineTest }) => { test(`testInfo.attach success in fixture`, async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
fixture: async ({}, use, testInfo) => { fixture: async ({}, use, testInfo) => {
const filePath = testInfo.outputPath('foo.txt'); const filePath = testInfo.outputPath('foo.txt');
require('fs').writeFileSync(filePath, 'hello'); require('fs').writeFileSync(filePath, 'hello');
@ -160,8 +162,8 @@ test(`testInfo.attach success in fixture`, async ({ runInlineTest }) => {
test(`testInfo.attach allow empty string body`, async ({ runInlineTest }) => { test(`testInfo.attach allow empty string body`, async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('success', async ({}, testInfo) => { test('success', async ({}, testInfo) => {
await testInfo.attach('name', { body: '', contentType: 'text/plain' }); await testInfo.attach('name', { body: '', contentType: 'text/plain' });
expect(0).toBe(1); expect(0).toBe(1);
@ -175,8 +177,8 @@ test(`testInfo.attach allow empty string body`, async ({ runInlineTest }) => {
test(`testInfo.attach allow empty buffer body`, async ({ runInlineTest }) => { test(`testInfo.attach allow empty buffer body`, async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('success', async ({}, testInfo) => { test('success', async ({}, testInfo) => {
await testInfo.attach('name', { body: Buffer.from(''), contentType: 'text/plain' }); await testInfo.attach('name', { body: Buffer.from(''), contentType: 'text/plain' });
expect(0).toBe(1); expect(0).toBe(1);
@ -190,8 +192,9 @@ test(`testInfo.attach allow empty buffer body`, async ({ runInlineTest }) => {
test(`testInfo.attach use name as prefix`, async ({ runInlineTest }) => { test(`testInfo.attach use name as prefix`, async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
fixture: async ({}, use, testInfo) => { fixture: async ({}, use, testInfo) => {
const filePath = testInfo.outputPath('foo.txt'); const filePath = testInfo.outputPath('foo.txt');
require('fs').writeFileSync(filePath, 'hello'); require('fs').writeFileSync(filePath, 'hello');
@ -213,8 +216,9 @@ test(`testInfo.attach use name as prefix`, async ({ runInlineTest }) => {
test(`testInfo.attach name should be sanitized`, async ({ runInlineTest }) => { test(`testInfo.attach name should be sanitized`, async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
fixture: async ({}, use, testInfo) => { fixture: async ({}, use, testInfo) => {
const filePath = testInfo.outputPath('foo.txt'); const filePath = testInfo.outputPath('foo.txt');
require('fs').writeFileSync(filePath, 'hello'); require('fs').writeFileSync(filePath, 'hello');
@ -236,8 +240,9 @@ test(`testInfo.attach name should be sanitized`, async ({ runInlineTest }) => {
test(`testInfo.attach name can be empty string`, async ({ runInlineTest }) => { test(`testInfo.attach name can be empty string`, async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
fixture: async ({}, use, testInfo) => { fixture: async ({}, use, testInfo) => {
const filePath = testInfo.outputPath('foo.txt'); const filePath = testInfo.outputPath('foo.txt');
require('fs').writeFileSync(filePath, 'hello'); require('fs').writeFileSync(filePath, 'hello');
@ -259,8 +264,9 @@ test(`testInfo.attach name can be empty string`, async ({ runInlineTest }) => {
test(`testInfo.attach throw if name is not string`, async ({ runInlineTest }) => { test(`testInfo.attach throw if name is not string`, async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
fixture: async ({}, use, testInfo) => { fixture: async ({}, use, testInfo) => {
const filePath = testInfo.outputPath('foo.txt'); const filePath = testInfo.outputPath('foo.txt');
require('fs').writeFileSync(filePath, 'hello'); require('fs').writeFileSync(filePath, 'hello');
@ -282,7 +288,7 @@ test(`testInfo.attach throw if name is not string`, async ({ runInlineTest }) =>
test('render text attachment with multiple lines', async ({ runInlineTest }) => { test('render text attachment with multiple lines', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; const { test, expect } = require('@playwright/test');
test('one', async ({}, testInfo) => { test('one', async ({}, testInfo) => {
testInfo.attachments.push({ testInfo.attachments.push({
name: 'attachment', name: 'attachment',

View File

@ -21,7 +21,7 @@ test('handle long test names', async ({ runInlineTest }) => {
const title = 'title'.repeat(30); const title = 'title'.repeat(30);
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('${title}', async ({}) => { test('${title}', async ({}) => {
expect(1).toBe(0); expect(1).toBe(0);
}); });
@ -34,7 +34,7 @@ test('handle long test names', async ({ runInlineTest }) => {
test('print the error name', async ({ runInlineTest }) => { test('print the error name', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('foobar', async ({}) => { test('foobar', async ({}) => {
const error = new Error('my-message'); const error = new Error('my-message');
error.name = 'FooBarError'; error.name = 'FooBarError';
@ -50,7 +50,7 @@ test('print the error name', async ({ runInlineTest }) => {
test('print should print the error name without a message', async ({ runInlineTest }) => { test('print should print the error name without a message', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('foobar', async ({}) => { test('foobar', async ({}) => {
const error = new Error(); const error = new Error();
error.name = 'FooBarError'; error.name = 'FooBarError';
@ -66,7 +66,7 @@ test('print should print the error name without a message', async ({ runInlineTe
test('should print an error in a codeframe', async ({ runInlineTest }) => { test('should print an error in a codeframe', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('foobar', async ({}) => { test('foobar', async ({}) => {
const error = new Error('my-message'); const error = new Error('my-message');
error.name = 'FooBarError'; error.name = 'FooBarError';
@ -79,10 +79,10 @@ test('should print an error in a codeframe', async ({ runInlineTest }) => {
expect(result.exitCode).toBe(1); expect(result.exitCode).toBe(1);
expect(result.failed).toBe(1); expect(result.failed).toBe(1);
expect(result.output).toContain('FooBarError: my-message'); expect(result.output).toContain('FooBarError: my-message');
expect(result.output).not.toContain('at a.spec.ts:7'); expect(result.output).not.toContain('at a.spec.ts:5');
expect(result.output).toContain(` 5 | const { test } = pwt;`); expect(result.output).toContain(` 2 | import { test, expect } from '@playwright/test';`);
expect(result.output).toContain(` 6 | test('foobar', async ({}) => {`); expect(result.output).toContain(` 3 | test('foobar', async ({}) => {`);
expect(result.output).toContain(`> 7 | const error = new Error('my-message');`); expect(result.output).toContain(`> 4 | const error = new Error('my-message');`);
}); });
test('should filter out node_modules error in a codeframe', async ({ runInlineTest }) => { test('should filter out node_modules error in a codeframe', async ({ runInlineTest }) => {
@ -95,7 +95,7 @@ test('should filter out node_modules error in a codeframe', async ({ runInlineTe
module.exports = { assert }; module.exports = { assert };
`, `,
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
const { assert } = require('utils/utils.js'); const { assert } = require('utils/utils.js');
test('fail', async ({}) => { test('fail', async ({}) => {
assert(false); assert(false);
@ -106,12 +106,12 @@ test('should filter out node_modules error in a codeframe', async ({ runInlineTe
expect(result.failed).toBe(1); expect(result.failed).toBe(1);
const output = result.output; const output = result.output;
expect(output).toContain('Error: Assertion error'); expect(output).toContain('Error: Assertion error');
expect(output).toContain('a.spec.ts:7:7 fail'); expect(output).toContain('a.spec.ts:4:11 fail');
expect(output).toContain(` 7 | test('fail', async ({}) => {`); expect(output).toContain(` 4 | test('fail', async ({}) => {`);
expect(output).toContain(`> 8 | assert(false);`); expect(output).toContain(`> 5 | assert(false);`);
expect(output).toContain(` | ^`); expect(output).toContain(` | ^`);
expect(output).toContain(`utils.js:6`); expect(output).toContain(`utils.js:4`);
expect(output).toContain(`a.spec.ts:8:9`); expect(output).toContain(`a.spec.ts:5:9`);
}); });
test('should print codeframe from a helper', async ({ runInlineTest }) => { test('should print codeframe from a helper', async ({ runInlineTest }) => {
@ -123,7 +123,7 @@ test('should print codeframe from a helper', async ({ runInlineTest }) => {
`, `,
'a.spec.ts': ` 'a.spec.ts': `
import { ohMy } from './helper'; import { ohMy } from './helper';
const { test } = pwt; import { test, expect } from '@playwright/test';
test('foobar', async ({}) => { test('foobar', async ({}) => {
ohMy(); ohMy();
}); });
@ -134,8 +134,8 @@ test('should print codeframe from a helper', async ({ runInlineTest }) => {
expect(result.exitCode).toBe(1); expect(result.exitCode).toBe(1);
expect(result.failed).toBe(1); expect(result.failed).toBe(1);
expect(result.output).toContain('Error: oh my'); expect(result.output).toContain('Error: oh my');
expect(result.output).toContain(` 4 | export function ohMy() {`); expect(result.output).toContain(` 2 | export function ohMy() {`);
expect(result.output).toContain(` > 5 | throw new Error('oh my');`); expect(result.output).toContain(` > 3 | throw new Error('oh my');`);
expect(result.output).toContain(` | ^`); expect(result.output).toContain(` | ^`);
}); });
@ -153,13 +153,13 @@ test('should print slow tests', async ({ runInlineTest }) => {
}; };
`, `,
'dir/a.test.js': ` 'dir/a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('slow test', async ({}) => { test('slow test', async ({}) => {
await new Promise(f => setTimeout(f, 1000)); await new Promise(f => setTimeout(f, 1000));
}); });
`, `,
'dir/b.test.js': ` 'dir/b.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('fast test', async ({}) => { test('fast test', async ({}) => {
await new Promise(f => setTimeout(f, 100)); await new Promise(f => setTimeout(f, 100));
}); });
@ -186,7 +186,7 @@ test('should not print slow parallel tests', async ({ runInlineTest }) => {
}; };
`, `,
'dir/a.test.js': ` 'dir/a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.describe.parallel('suite', () => { test.describe.parallel('suite', () => {
test('inner slow test', async ({}) => { test('inner slow test', async ({}) => {
await new Promise(f => setTimeout(f, 1000)); await new Promise(f => setTimeout(f, 1000));
@ -214,7 +214,7 @@ test('should not print slow tests', async ({ runInlineTest }) => {
}; };
`, `,
'dir/a.test.js': ` 'dir/a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('slow test', async ({}) => { test('slow test', async ({}) => {
await new Promise(f => setTimeout(f, 1000)); await new Promise(f => setTimeout(f, 1000));
}); });
@ -231,7 +231,7 @@ test('should not print slow tests', async ({ runInlineTest }) => {
test('should print flaky failures', async ({ runInlineTest }) => { test('should print flaky failures', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('foobar', async ({}, testInfo) => { test('foobar', async ({}, testInfo) => {
expect(testInfo.retry).toBe(1); expect(testInfo.retry).toBe(1);
}); });
@ -245,7 +245,7 @@ test('should print flaky failures', async ({ runInlineTest }) => {
test('should print flaky timeouts', async ({ runInlineTest }) => { test('should print flaky timeouts', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('foobar', async ({}, testInfo) => { test('foobar', async ({}, testInfo) => {
if (!testInfo.retry) if (!testInfo.retry)
await new Promise(f => setTimeout(f, 2000)); await new Promise(f => setTimeout(f, 2000));
@ -260,7 +260,7 @@ test('should print flaky timeouts', async ({ runInlineTest }) => {
test('should print stack-less errors', async ({ runInlineTest }) => { test('should print stack-less errors', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('foobar', async ({}) => { test('foobar', async ({}) => {
const e = new Error('Hello'); const e = new Error('Hello');
delete e.stack; delete e.stack;
@ -276,7 +276,7 @@ test('should print stack-less errors', async ({ runInlineTest }) => {
test('should print errors with inconsistent message/stack', async ({ runInlineTest }) => { test('should print errors with inconsistent message/stack', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('foobar', async function myTest({}) { test('foobar', async function myTest({}) {
const e = new Error('Hello'); const e = new Error('Hello');
// Force stack to contain "Hello". // Force stack to contain "Hello".
@ -304,7 +304,7 @@ test('should print "no tests found" error', async ({ runInlineTest }) => {
test('should not crash on undefined body with manual attachments', async ({ runInlineTest }) => { test('should not crash on undefined body with manual attachments', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('one', async ({}, testInfo) => { test('one', async ({}, testInfo) => {
testInfo.attachments.push({ testInfo.attachments.push({
name: 'foo.txt', name: 'foo.txt',
@ -323,7 +323,8 @@ test('should not crash on undefined body with manual attachments', async ({ runI
test('should report fatal errors at the end', async ({ runInlineTest }) => { test('should report fatal errors at the end', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
fixture: [async ({ }, use) => { fixture: [async ({ }, use) => {
await use(); await use();
throw new Error('oh my!'); throw new Error('oh my!');
@ -333,7 +334,8 @@ test('should report fatal errors at the end', async ({ runInlineTest }) => {
}); });
`, `,
'b.spec.ts': ` 'b.spec.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
fixture: [async ({ }, use) => { fixture: [async ({ }, use) => {
await use(); await use();
throw new Error('oh my!'); throw new Error('oh my!');
@ -351,7 +353,7 @@ test('should report fatal errors at the end', async ({ runInlineTest }) => {
test('should contain at most 1 decimal for humanized timing', async ({ runInlineTest }) => { test('should contain at most 1 decimal for humanized timing', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('should work', () => {}); test('should work', () => {});
` `
}); });

View File

@ -20,7 +20,7 @@ import { test, expect } from './playwright-test-fixtures';
test('render expected', async ({ runInlineTest }) => { test('render expected', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('one', async ({}) => { test('one', async ({}) => {
expect(1).toBe(1); expect(1).toBe(1);
}); });
@ -33,7 +33,7 @@ test('render expected', async ({ runInlineTest }) => {
test('render unexpected', async ({ runInlineTest }) => { test('render unexpected', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('one', async ({}) => { test('one', async ({}) => {
expect(1).toBe(0); expect(1).toBe(0);
}); });
@ -46,7 +46,7 @@ test('render unexpected', async ({ runInlineTest }) => {
test('render unexpected after retry', async ({ runInlineTest }) => { test('render unexpected after retry', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('one', async ({}) => { test('one', async ({}) => {
expect(1).toBe(0); expect(1).toBe(0);
}); });
@ -61,7 +61,7 @@ test('render unexpected after retry', async ({ runInlineTest }) => {
test('render flaky', async ({ runInlineTest }) => { test('render flaky', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('one', async ({}, testInfo) => { test('one', async ({}, testInfo) => {
expect(testInfo.retry).toBe(3); expect(testInfo.retry).toBe(3);
}); });
@ -81,7 +81,7 @@ test('should work from config', async ({ runInlineTest }) => {
module.exports = { reporter: 'dot' }; module.exports = { reporter: 'dot' };
`, `,
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('one', async ({}) => { test('one', async ({}) => {
expect(1).toBe(1); expect(1).toBe(1);
}); });
@ -94,7 +94,7 @@ test('should work from config', async ({ runInlineTest }) => {
test('render 243 tests in rows by 80', async ({ runInlineTest }) => { test('render 243 tests in rows by 80', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
for (let i = 0; i < 243; i++) { for (let i = 0; i < 243; i++) {
test('test' + i, () => {}); test('test' + i, () => {});
} }

View File

@ -26,7 +26,7 @@ function relativeFilePath(file: string): string {
test('print GitHub annotations for success', async ({ runInlineTest }) => { test('print GitHub annotations for success', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('example1', async ({}) => { test('example1', async ({}) => {
expect(1 + 1).toBe(2); expect(1 + 1).toBe(2);
}); });
@ -41,7 +41,7 @@ test('print GitHub annotations for success', async ({ runInlineTest }) => {
test('print GitHub annotations for failed tests', async ({ runInlineTest }, testInfo) => { test('print GitHub annotations for failed tests', async ({ runInlineTest }, testInfo) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; const { test, expect } = require('@playwright/test');
test('example', async ({}) => { test('example', async ({}) => {
expect(1 + 1).toBe(3); expect(1 + 1).toBe(3);
}); });
@ -49,9 +49,9 @@ test('print GitHub annotations for failed tests', async ({ runInlineTest }, test
}, { retries: 3, reporter: 'github' }, { GITHUB_WORKSPACE: process.cwd() }); }, { retries: 3, reporter: 'github' }, { GITHUB_WORKSPACE: process.cwd() });
const text = result.output; const text = result.output;
const testPath = relativeFilePath(testInfo.outputPath('a.test.js')); const testPath = relativeFilePath(testInfo.outputPath('a.test.js'));
expect(text).toContain(`::error file=${testPath},title=a.test.js:6:7 example,line=7,col=23:: 1) a.test.js:6:7 example ───────────────────────────────────────────────────────────────────────%0A%0A Retry #1`); expect(text).toContain(`::error file=${testPath},title=a.test.js:3:7 example,line=4,col=23:: 1) a.test.js:3:7 example ───────────────────────────────────────────────────────────────────────%0A%0A Retry #1`);
expect(text).toContain(`::error file=${testPath},title=a.test.js:6:7 example,line=7,col=23:: 1) a.test.js:6:7 example ───────────────────────────────────────────────────────────────────────%0A%0A Retry #2`); expect(text).toContain(`::error file=${testPath},title=a.test.js:3:7 example,line=4,col=23:: 1) a.test.js:3:7 example ───────────────────────────────────────────────────────────────────────%0A%0A Retry #2`);
expect(text).toContain(`::error file=${testPath},title=a.test.js:6:7 example,line=7,col=23:: 1) a.test.js:6:7 example ───────────────────────────────────────────────────────────────────────%0A%0A Retry #3`); expect(text).toContain(`::error file=${testPath},title=a.test.js:3:7 example,line=4,col=23:: 1) a.test.js:3:7 example ───────────────────────────────────────────────────────────────────────%0A%0A Retry #3`);
expect(result.exitCode).toBe(1); expect(result.exitCode).toBe(1);
}); });
@ -63,7 +63,7 @@ test('print GitHub annotations for slow tests', async ({ runInlineTest }) => {
}; };
`, `,
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('slow test', async ({}) => { test('slow test', async ({}) => {
await new Promise(f => setTimeout(f, 200)); await new Promise(f => setTimeout(f, 200));
}); });
@ -77,8 +77,9 @@ test('print GitHub annotations for slow tests', async ({ runInlineTest }) => {
test('print GitHub annotations for global error', async ({ runInlineTest }) => { test('print GitHub annotations for global error', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
w: [async ({}, use) => { w: [async ({}, use) => {
await use(); await use();
throw new Error('Oh my!'); throw new Error('Oh my!');

View File

@ -43,7 +43,7 @@ test('should generate report', async ({ runInlineTest, showReport, page }) => {
module.exports = { name: 'project-name' }; module.exports = { name: 'project-name' };
`, `,
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('passes', async ({}) => {}); test('passes', async ({}) => {});
test('fails', async ({}) => { test('fails', async ({}) => {
expect(1).toBe(2); expect(1).toBe(2);
@ -83,7 +83,7 @@ test('should not throw when attachment is missing', async ({ runInlineTest, page
module.exports = { preserveOutput: 'failures-only' }; module.exports = { preserveOutput: 'failures-only' };
`, `,
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('passes', async ({ page }, testInfo) => { test('passes', async ({ page }, testInfo) => {
const screenshot = testInfo.outputPath('screenshot.png'); const screenshot = testInfo.outputPath('screenshot.png');
await page.screenshot({ path: screenshot }); await page.screenshot({ path: screenshot });
@ -111,7 +111,7 @@ test('should include image diff', async ({ runInlineTest, page, showReport }) =>
'a.test.js-snapshots/expected-darwin.png': expected, 'a.test.js-snapshots/expected-darwin.png': expected,
'a.test.js-snapshots/expected-win32.png': expected, 'a.test.js-snapshots/expected-win32.png': expected,
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('fails', async ({ page }, testInfo) => { test('fails', async ({ page }, testInfo) => {
await page.setContent('<html>Hello World</html>'); await page.setContent('<html>Hello World</html>');
const screenshot = await page.screenshot(); const screenshot = await page.screenshot();
@ -172,7 +172,7 @@ test('should include multiple image diffs', async ({ runInlineTest, page, showRe
'__screenshots__/a.test.js/fails-2.png': whiteImage, '__screenshots__/a.test.js/fails-2.png': whiteImage,
'__screenshots__/a.test.js/fails-3.png': redImage, '__screenshots__/a.test.js/fails-3.png': redImage,
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('fails', async ({ page }, testInfo) => { test('fails', async ({ page }, testInfo) => {
testInfo.snapshotSuffix = ''; testInfo.snapshotSuffix = '';
await expect.soft(page).toHaveScreenshot({ timeout: 1000 }); await expect.soft(page).toHaveScreenshot({ timeout: 1000 });
@ -206,7 +206,7 @@ test('should include image diffs for same expectation', async ({ runInlineTest,
'a.test.js-snapshots/expected-darwin.png': expected, 'a.test.js-snapshots/expected-darwin.png': expected,
'a.test.js-snapshots/expected-win32.png': expected, 'a.test.js-snapshots/expected-win32.png': expected,
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('fails', async ({ page }, testInfo) => { test('fails', async ({ page }, testInfo) => {
await page.setContent('<html>Hello World</html>'); await page.setContent('<html>Hello World</html>');
const screenshot = await page.screenshot(); const screenshot = await page.screenshot();
@ -235,7 +235,7 @@ test('should include image diff when screenshot failed to generate due to animat
module.exports = { use: { viewport: { width: 200, height: 200 }} }; module.exports = { use: { viewport: { width: 200, height: 200 }} };
`, `,
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('fails', async ({ page }, testInfo) => { test('fails', async ({ page }, testInfo) => {
testInfo.snapshotSuffix = ''; testInfo.snapshotSuffix = '';
await page.evaluate(() => { await page.evaluate(() => {
@ -279,7 +279,7 @@ test('should not include image diff with non-images', async ({ runInlineTest, pa
'a.test.js-snapshots/expected-darwin': expected, 'a.test.js-snapshots/expected-darwin': expected,
'a.test.js-snapshots/expected-win32': expected, 'a.test.js-snapshots/expected-win32': expected,
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('fails', async ({ page }, testInfo) => { test('fails', async ({ page }, testInfo) => {
await page.setContent('<html>Hello World</html>'); await page.setContent('<html>Hello World</html>');
const screenshot = await page.screenshot(); const screenshot = await page.screenshot();
@ -309,7 +309,7 @@ test('should include screenshot on failure', async ({ runInlineTest, page, showR
}; };
`, `,
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('fails', async ({ page }) => { test('fails', async ({ page }) => {
await page.setContent('<html>Failed state</html>'); await page.setContent('<html>Failed state</html>');
await expect(true).toBeFalsy(); await expect(true).toBeFalsy();
@ -330,7 +330,7 @@ test('should include screenshot on failure', async ({ runInlineTest, page, showR
test('should include stdio', async ({ runInlineTest, page, showReport }) => { test('should include stdio', async ({ runInlineTest, page, showReport }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('fails', async ({ page }) => { test('fails', async ({ page }) => {
console.log('First line'); console.log('First line');
console.log('Second line'); console.log('Second line');
@ -353,7 +353,7 @@ test('should include stdio', async ({ runInlineTest, page, showReport }) => {
test('should highlight error', async ({ runInlineTest, page, showReport }) => { test('should highlight error', async ({ runInlineTest, page, showReport }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('fails', async ({ page }) => { test('fails', async ({ page }) => {
await expect(true).toBeFalsy(); await expect(true).toBeFalsy();
}); });
@ -373,7 +373,7 @@ test('should show trace source', async ({ runInlineTest, page, showReport }) =>
module.exports = { use: { trace: 'on' } }; module.exports = { use: { trace: 'on' } };
`, `,
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('passes', async ({ page }) => { test('passes', async ({ page }) => {
await page.evaluate('2 + 2'); await page.evaluate('2 + 2');
}); });
@ -389,7 +389,7 @@ test('should show trace source', async ({ runInlineTest, page, showReport }) =>
await page.click('text=Source'); await page.click('text=Source');
await expect(page.locator('.CodeMirror-line')).toContainText([ await expect(page.locator('.CodeMirror-line')).toContainText([
/const.*pwt;/, /import.*test/,
/page\.evaluate/ /page\.evaluate/
]); ]);
await expect(page.locator('.source-line-running')).toContainText('page.evaluate'); await expect(page.locator('.source-line-running')).toContainText('page.evaluate');
@ -406,7 +406,7 @@ test('should show trace title', async ({ runInlineTest, page, showReport }) => {
module.exports = { use: { trace: 'on' } }; module.exports = { use: { trace: 'on' } };
`, `,
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('passes', async ({ page }) => { test('passes', async ({ page }) => {
await page.evaluate('2 + 2'); await page.evaluate('2 + 2');
}); });
@ -418,7 +418,7 @@ test('should show trace title', async ({ runInlineTest, page, showReport }) => {
await showReport(); await showReport();
await page.click('text=passes'); await page.click('text=passes');
await page.click('img'); await page.click('img');
await expect(page.locator('.workbench .title')).toHaveText('a.test.js:6 passes'); 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 }) => {
@ -427,7 +427,7 @@ test('should show multi trace source', async ({ runInlineTest, page, server, sho
module.exports = { use: { trace: 'on' } }; module.exports = { use: { trace: 'on' } };
`, `,
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('passes', async ({ playwright, page }) => { test('passes', async ({ playwright, page }) => {
await page.evaluate('2 + 2'); await page.evaluate('2 + 2');
const request = await playwright.request.newContext(); const request = await playwright.request.newContext();
@ -461,7 +461,7 @@ test('should warn user when viewing via file:// protocol', async ({ runInlineTes
module.exports = { use: { trace: 'on' } }; module.exports = { use: { trace: 'on' } };
`, `,
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('passes', async ({ page }) => { test('passes', async ({ page }) => {
await page.evaluate('2 + 2'); await page.evaluate('2 + 2');
}); });
@ -492,7 +492,7 @@ test('should show failed and timed out steps and hooks', async ({ runInlineTest,
module.exports = { timeout: 3000 }; module.exports = { timeout: 3000 };
`, `,
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.beforeAll(() => { test.beforeAll(() => {
console.log('beforeAll 1'); console.log('beforeAll 1');
}); });
@ -563,7 +563,7 @@ test('should render annotations', async ({ runInlineTest, page, showReport }) =>
module.exports = { timeout: 1500 }; module.exports = { timeout: 1500 };
`, `,
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('skipped test', async ({ page }) => { test('skipped test', async ({ page }) => {
test.skip(true, 'I am not interested in this test'); test.skip(true, 'I am not interested in this test');
}); });
@ -580,7 +580,7 @@ test('should render annotations', async ({ runInlineTest, page, showReport }) =>
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({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('passing', async ({ page }, testInfo) => { test('passing', async ({ page }, testInfo) => {
testInfo.attachments.push({ testInfo.attachments.push({
name: 'example.txt', name: 'example.txt',
@ -621,7 +621,7 @@ test('should render text attachments as text', async ({ runInlineTest, page, sho
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({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('passing', async ({ page }, testInfo) => { test('passing', async ({ page }, testInfo) => {
await testInfo.attach('screenshot', { body: await page.screenshot(), contentType: 'image/png' }); await testInfo.attach('screenshot', { body: await page.screenshot(), contentType: 'image/png' });
await testInfo.attach('some-pdf', { body: Buffer.from('foo'), contentType: 'application/pdf' }); await testInfo.attach('some-pdf', { body: Buffer.from('foo'), contentType: 'application/pdf' });
@ -645,10 +645,12 @@ test('should use file-browser friendly extensions for buffer attachments based o
])); ]));
}); });
test('should strikethough textual diff', async ({ runInlineTest, showReport, page }) => { test('should strikethrough textual diff', async ({ runInlineTest, showReport, page }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'helper.ts': ` 'helper.ts': `
export const test = pwt.test.extend({ import { test as base } from '@playwright/test';
export * from '@playwright/test';
export const test = base.extend({
auto: [ async ({}, run, testInfo) => { auto: [ async ({}, run, testInfo) => {
testInfo.snapshotSuffix = ''; testInfo.snapshotSuffix = '';
await run(); await run();
@ -657,7 +659,7 @@ test('should strikethough textual diff', async ({ runInlineTest, showReport, pag
`, `,
'a.spec.js-snapshots/snapshot.txt': `old`, 'a.spec.js-snapshots/snapshot.txt': `old`,
'a.spec.js': ` 'a.spec.js': `
const { test } = require('./helper'); const { test, expect } = require('./helper');
test('is a test', ({}) => { test('is a test', ({}) => {
expect('new').toMatchSnapshot('snapshot.txt'); expect('new').toMatchSnapshot('snapshot.txt');
}); });
@ -670,10 +672,12 @@ test('should strikethough textual diff', async ({ runInlineTest, showReport, pag
expect(stricken).toBe('old'); expect(stricken).toBe('old');
}); });
test('should strikethough textual diff with commonalities', async ({ runInlineTest, showReport, page }) => { test('should strikethrough textual diff with commonalities', async ({ runInlineTest, showReport, page }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'helper.ts': ` 'helper.ts': `
export const test = pwt.test.extend({ import { test as base } from '@playwright/test';
export * from '@playwright/test';
export const test = base.extend({
auto: [ async ({}, run, testInfo) => { auto: [ async ({}, run, testInfo) => {
testInfo.snapshotSuffix = ''; testInfo.snapshotSuffix = '';
await run(); await run();
@ -682,7 +686,7 @@ test('should strikethough textual diff with commonalities', async ({ runInlineTe
`, `,
'a.spec.js-snapshots/snapshot.txt': `oldcommon`, 'a.spec.js-snapshots/snapshot.txt': `oldcommon`,
'a.spec.js': ` 'a.spec.js': `
const { test } = require('./helper'); const { test, expect } = require('./helper');
test('is a test', ({}) => { test('is a test', ({}) => {
expect('newcommon').toMatchSnapshot('snapshot.txt'); expect('newcommon').toMatchSnapshot('snapshot.txt');
}); });
@ -699,7 +703,7 @@ test('should differentiate repeat-each test cases', async ({ runInlineTest, show
test.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/10859' }); test.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/10859' });
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.js': ` 'a.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('sample', async ({}, testInfo) => { test('sample', async ({}, testInfo) => {
if (testInfo.repeatEachIndex === 2) if (testInfo.repeatEachIndex === 2)
throw new Error('ouch'); throw new Error('ouch');
@ -722,7 +726,7 @@ test('should group similar / loop steps', async ({ runInlineTest, showReport, pa
test.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/10098' }); test.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/10098' });
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.js': ` 'a.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('sample', async ({}, testInfo) => { test('sample', async ({}, testInfo) => {
for (let i = 0; i < 10; ++i) for (let i = 0; i < 10; ++i)
expect(1).toBe(1); expect(1).toBe(1);
@ -745,7 +749,7 @@ test('open tests from required file', async ({ runInlineTest, showReport, page }
test.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/11742' }); test.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/11742' });
const result = await runInlineTest({ const result = await runInlineTest({
'inner.js': ` 'inner.js': `
const { test, expect } = pwt; const { test, expect } = require('@playwright/test');
test('sample', async ({}) => { expect(2).toBe(2); }); test('sample', async ({}) => { expect(2).toBe(2); });
`, `,
'a.spec.js': `require('./inner')` 'a.spec.js': `require('./inner')`
@ -765,11 +769,11 @@ test.describe('gitCommitInfo plugin', () => {
'uncommitted.txt': `uncommitted file`, 'uncommitted.txt': `uncommitted file`,
'playwright.config.ts': ` 'playwright.config.ts': `
import { gitCommitInfo } from '@playwright/test/lib/plugins'; import { gitCommitInfo } from '@playwright/test/lib/plugins';
const { test } = pwt; import { test, expect } from '@playwright/test';
export default { _plugins: [gitCommitInfo()] }; export default { _plugins: [gitCommitInfo()] };
`, `,
'example.spec.ts': ` 'example.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('sample', async ({}) => { expect(2).toBe(2); }); test('sample', async ({}) => { expect(2).toBe(2); });
`, `,
}; };
@ -818,7 +822,7 @@ test.describe('gitCommitInfo plugin', () => {
'uncommitted.txt': `uncommitted file`, 'uncommitted.txt': `uncommitted file`,
'playwright.config.ts': ` 'playwright.config.ts': `
import { gitCommitInfo } from '@playwright/test/lib/plugins'; import { gitCommitInfo } from '@playwright/test/lib/plugins';
const { test } = pwt; import { test, expect } from '@playwright/test';
const plugin = gitCommitInfo({ const plugin = gitCommitInfo({
info: { info: {
'revision.id': '1234567890', 'revision.id': '1234567890',
@ -832,7 +836,7 @@ test.describe('gitCommitInfo plugin', () => {
`, `,
'example.spec.ts': ` 'example.spec.ts': `
import { gitCommitInfo } from '@playwright/test/lib/plugins'; import { gitCommitInfo } from '@playwright/test/lib/plugins';
const { test } = pwt; import { test, expect } from '@playwright/test';
test('sample', async ({}) => { expect(2).toBe(2); }); test('sample', async ({}) => { expect(2).toBe(2); });
`, `,
}, { reporter: 'dot,html' }, { PW_TEST_HTML_REPORT_OPEN: 'never', GITHUB_REPOSITORY: 'microsoft/playwright-example-for-test', GITHUB_RUN_ID: 'example-run-id', GITHUB_SERVER_URL: 'https://playwright.dev', GITHUB_SHA: 'example-sha' }, undefined); }, { reporter: 'dot,html' }, { PW_TEST_HTML_REPORT_OPEN: 'never', GITHUB_REPOSITORY: 'microsoft/playwright-example-for-test', GITHUB_RUN_ID: 'example-run-id', GITHUB_SERVER_URL: 'https://playwright.dev', GITHUB_SHA: 'example-sha' }, undefined);
@ -860,7 +864,7 @@ test.describe('gitCommitInfo plugin', () => {
export default {}; export default {};
`, `,
'example.spec.ts': ` 'example.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('my sample test', async ({}) => { expect(2).toBe(2); }); test('my sample test', async ({}) => { expect(2).toBe(2); });
`, `,
}, { reporter: 'dot,html' }, { PW_TEST_HTML_REPORT_OPEN: 'never' }, undefined); }, { reporter: 'dot,html' }, { PW_TEST_HTML_REPORT_OPEN: 'never' }, undefined);
@ -884,7 +888,7 @@ test.describe('gitCommitInfo plugin', () => {
}; };
`, `,
'example.spec.ts': ` 'example.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('my sample test', async ({}) => { expect(2).toBe(2); }); test('my sample test', async ({}) => { expect(2).toBe(2); });
`, `,
}, { reporter: 'dot,html' }, { PW_TEST_HTML_REPORT_OPEN: 'never' }); }, { reporter: 'dot,html' }, { PW_TEST_HTML_REPORT_OPEN: 'never' });
@ -906,7 +910,7 @@ test('should report clashing folders', async ({ runInlineTest }) => {
} }
`, `,
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('passes', async ({}) => { test('passes', async ({}) => {
}); });
`, `,
@ -924,7 +928,7 @@ test.describe('report location', () => {
module.exports = { reporter: [['html', { outputFolder: '../my-report/' }]] }; module.exports = { reporter: [['html', { outputFolder: '../my-report/' }]] };
`, `,
'nested/project/a.test.js': ` 'nested/project/a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('one', async ({}) => { test('one', async ({}) => {
expect(1).toBe(1); expect(1).toBe(1);
}); });
@ -942,7 +946,7 @@ test.describe('report location', () => {
module.exports = { projects: [ {} ] }; module.exports = { projects: [ {} ] };
`, `,
'foo/bar/baz/tests/a.spec.js': ` 'foo/bar/baz/tests/a.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
const fs = require('fs'); const fs = require('fs');
test('pass', ({}, testInfo) => { test('pass', ({}, testInfo) => {
}); });
@ -967,7 +971,7 @@ test.describe('report location', () => {
module.exports = { projects: [ {} ] }; module.exports = { projects: [ {} ] };
`, `,
'foo/bar/baz/tests/a.spec.js': ` 'foo/bar/baz/tests/a.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
const fs = require('fs'); const fs = require('fs');
test('pass', ({}, testInfo) => { test('pass', ({}, testInfo) => {
}); });
@ -993,7 +997,7 @@ test('should shard report', async ({ runInlineTest, showReport, page }, testInfo
}; };
for (let i = 0; i < totalShards; i++) { for (let i = 0; i < totalShards; i++) {
testFiles[`a-${i}.spec.ts`] = ` testFiles[`a-${i}.spec.ts`] = `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('passes', async ({}) => { expect(2).toBe(2); }); test('passes', async ({}) => { expect(2).toBe(2); });
test('fails', async ({}) => { expect(1).toBe(2); }); test('fails', async ({}) => { expect(1).toBe(2); });
test('skipped', async ({}) => { test.skip('Does not work') }); test('skipped', async ({}) => { test.skip('Does not work') });
@ -1043,7 +1047,7 @@ test('should pad report numbers with zeros', async ({ runInlineTest }, testInfo)
}; };
for (let i = 0; i < 100; i++) { for (let i = 0; i < 100; i++) {
testFiles[`a-${i}.spec.ts`] = ` testFiles[`a-${i}.spec.ts`] = `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('passes', async ({}) => { }); test('passes', async ({}) => { });
`; `;
} }
@ -1066,7 +1070,7 @@ test('should show report with missing shards', async ({ runInlineTest, showRepor
}; };
for (let i = 0; i < totalShards; i++) { for (let i = 0; i < totalShards; i++) {
testFiles[`a-${String(i).padStart(2, '0')}.spec.ts`] = ` testFiles[`a-${String(i).padStart(2, '0')}.spec.ts`] = `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('passes', async ({}) => { expect(2).toBe(2); }); test('passes', async ({}) => { expect(2).toBe(2); });
test('fails', async ({}) => { expect(1).toBe(2); }); test('fails', async ({}) => { expect(1).toBe(2); });
test('skipped', async ({}) => { test.skip('Does not work') }); test('skipped', async ({}) => { test.skip('Does not work') });
@ -1118,7 +1122,7 @@ test('should produce single file report when shard: false', async ({ runInlineTe
const testFiles = {}; const testFiles = {};
for (let i = 0; i < totalShards; i++) { for (let i = 0; i < totalShards; i++) {
testFiles[`a-${String(i).padStart(2, '0')}.spec.ts`] = ` testFiles[`a-${String(i).padStart(2, '0')}.spec.ts`] = `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('passes', async ({}) => { expect(2).toBe(2); }); test('passes', async ({}) => { expect(2).toBe(2); });
test('fails', async ({}) => { expect(1).toBe(2); }); test('fails', async ({}) => { expect(1).toBe(2); });
test('skipped', async ({}) => { test.skip('Does not work') }); test('skipped', async ({}) => { test.skip('Does not work') });

View File

@ -21,7 +21,7 @@ import { test, expect, stripAnsi } from './playwright-test-fixtures';
test('should support spec.ok', async ({ runInlineTest }) => { test('should support spec.ok', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('math works!', async ({}) => { test('math works!', async ({}) => {
expect(1 + 1).toBe(2); expect(1 + 1).toBe(2);
}); });
@ -38,7 +38,7 @@ test('should support spec.ok', async ({ runInlineTest }) => {
test('should not report skipped due to sharding', async ({ runInlineTest }) => { test('should not report skipped due to sharding', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('one', async () => { test('one', async () => {
}); });
test('two', async () => { test('two', async () => {
@ -46,7 +46,7 @@ test('should not report skipped due to sharding', async ({ runInlineTest }) => {
}); });
`, `,
'b.test.js': ` 'b.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('three', async () => { test('three', async () => {
}); });
test('four', async () => { test('four', async () => {
@ -83,7 +83,7 @@ test('should report projects', async ({ runInlineTest }, testInfo) => {
}; };
`, `,
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('math works!', async ({}) => { test('math works!', async ({}) => {
expect(1 + 1).toBe(2); expect(1 + 1).toBe(2);
}); });
@ -112,7 +112,7 @@ test('should report projects', async ({ runInlineTest }, testInfo) => {
test('should show steps', async ({ runInlineTest }) => { test('should show steps', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('math works!', async ({}) => { test('math works!', async ({}) => {
expect(1 + 1).toBe(2); expect(1 + 1).toBe(2);
await test.step('math works in a step', async () => { await test.step('math works in a step', async () => {
@ -149,7 +149,7 @@ test('should show steps', async ({ runInlineTest }) => {
test('should display tags separately from title', async ({ runInlineTest }) => { test('should display tags separately from title', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('math works! @USR-MATH-001 @USR-MATH-002', async ({}) => { test('math works! @USR-MATH-001 @USR-MATH-002', async ({}) => {
expect(1 + 1).toBe(2); expect(1 + 1).toBe(2);
await test.step('math works in a step', async () => { await test.step('math works in a step', async () => {
@ -178,7 +178,7 @@ test('should display tags separately from title', async ({ runInlineTest }) => {
test('should have relative always-posix paths', async ({ runInlineTest }) => { test('should have relative always-posix paths', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; const { test, expect } = require('@playwright/test');
test('math works!', async ({}) => { test('math works!', async ({}) => {
expect(1 + 1).toBe(2); expect(1 + 1).toBe(2);
}); });
@ -187,7 +187,7 @@ test('should have relative always-posix paths', async ({ runInlineTest }) => {
expect(result.exitCode).toBe(0); expect(result.exitCode).toBe(0);
expect(result.report.config.rootDir.indexOf(path.win32.sep)).toBe(-1); expect(result.report.config.rootDir.indexOf(path.win32.sep)).toBe(-1);
expect(result.report.suites[0].specs[0].file).toBe('a.test.js'); expect(result.report.suites[0].specs[0].file).toBe('a.test.js');
expect(result.report.suites[0].specs[0].line).toBe(6); expect(result.report.suites[0].specs[0].line).toBe(3);
expect(result.report.suites[0].specs[0].column).toBe(7); expect(result.report.suites[0].specs[0].column).toBe(7);
}); });
@ -196,7 +196,7 @@ test('should have error position in results', async ({
}) => { }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; const { test, expect } = require('@playwright/test');
test('math works!', async ({}) => { test('math works!', async ({}) => {
expect(1 + 1).toBe(3); expect(1 + 1).toBe(3);
}); });
@ -204,7 +204,7 @@ test('should have error position in results', async ({
}); });
expect(result.exitCode).toBe(1); expect(result.exitCode).toBe(1);
expect(result.report.suites[0].specs[0].file).toBe('a.test.js'); expect(result.report.suites[0].specs[0].file).toBe('a.test.js');
expect(result.report.suites[0].specs[0].tests[0].results[0].errorLocation!.line).toBe(7); expect(result.report.suites[0].specs[0].tests[0].results[0].errorLocation!.line).toBe(4);
expect(result.report.suites[0].specs[0].tests[0].results[0].errorLocation!.column).toBe(23); expect(result.report.suites[0].specs[0].tests[0].results[0].errorLocation!.column).toBe(23);
}); });
@ -214,7 +214,7 @@ test('should add dot in addition to file json with CI', async ({ runInlineTest }
module.exports = { reporter: [['json', { outputFile: 'a.json' }]] }; module.exports = { reporter: [['json', { outputFile: 'a.json' }]] };
`, `,
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('one', async ({}) => { test('one', async ({}) => {
expect(1).toBe(1); expect(1).toBe(1);
}); });
@ -231,20 +231,20 @@ test('should add line in addition to file json without CI', async ({ runInlineTe
module.exports = { reporter: [['json', { outputFile: 'a.json' }]] }; module.exports = { reporter: [['json', { outputFile: 'a.json' }]] };
`, `,
'a.test.js': ` 'a.test.js': `
const { test } = pwt; const { test, expect } = require('@playwright/test');
test('one', async ({}) => { test('one', async ({}) => {
expect(1).toBe(1); expect(1).toBe(1);
}); });
`, `,
}, { reporter: '' }, { PW_TEST_DEBUG_REPORTERS: '1' }); }, { reporter: '' }, { PW_TEST_DEBUG_REPORTERS: '1' });
expect(result.exitCode).toBe(0); expect(result.exitCode).toBe(0);
expect(result.output).toContain('[1/1] a.test.js:6:7 one'); expect(result.output).toContain('[1/1] a.test.js:3:7 one');
expect(fs.existsSync(testInfo.outputPath('a.json'))).toBeTruthy(); expect(fs.existsSync(testInfo.outputPath('a.json'))).toBeTruthy();
}); });
test('should have starting time in results', async ({ runInlineTest }, testInfo) => { test('should have starting time in results', async ({ runInlineTest }, testInfo) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('math works!', async ({}) => { test('math works!', async ({}) => {
expect(1 + 1).toBe(2); expect(1 + 1).toBe(2);
}); });
@ -262,7 +262,7 @@ test.describe('report location', () => {
module.exports = { reporter: [['json', { outputFile: '../my-report/a.json' }]] }; module.exports = { reporter: [['json', { outputFile: '../my-report/a.json' }]] };
`, `,
'nested/project/a.test.js': ` 'nested/project/a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('one', async ({}) => { test('one', async ({}) => {
expect(1).toBe(1); expect(1).toBe(1);
}); });
@ -280,7 +280,7 @@ test.describe('report location', () => {
module.exports = { projects: [ {} ] }; module.exports = { projects: [ {} ] };
`, `,
'foo/bar/baz/tests/a.spec.js': ` 'foo/bar/baz/tests/a.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
const fs = require('fs'); const fs = require('fs');
test('pass', ({}, testInfo) => { test('pass', ({}, testInfo) => {
}); });

View File

@ -22,13 +22,13 @@ import fs from 'fs';
test('should render expected', async ({ runInlineTest }) => { test('should render expected', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('one', async ({}) => { test('one', async ({}) => {
expect(1).toBe(1); expect(1).toBe(1);
}); });
`, `,
'b.test.js': ` 'b.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('two', async ({}) => { test('two', async ({}) => {
expect(1).toBe(1); expect(1).toBe(1);
}); });
@ -49,7 +49,7 @@ test('should render expected', async ({ runInlineTest }) => {
test('should render unexpected', async ({ runInlineTest }) => { test('should render unexpected', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('one', async ({}) => { test('one', async ({}) => {
expect(1).toBe(0); expect(1).toBe(0);
}); });
@ -69,7 +69,7 @@ test('should render unexpected', async ({ runInlineTest }) => {
test('should render unexpected after retry', async ({ runInlineTest }) => { test('should render unexpected after retry', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('one', async ({}) => { test('one', async ({}) => {
expect(1).toBe(0); expect(1).toBe(0);
}); });
@ -87,7 +87,7 @@ test('should render unexpected after retry', async ({ runInlineTest }) => {
test('should render flaky', async ({ runInlineTest }) => { test('should render flaky', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('one', async ({}, testInfo) => { test('one', async ({}, testInfo) => {
expect(testInfo.retry).toBe(3); expect(testInfo.retry).toBe(3);
}); });
@ -101,7 +101,7 @@ test('should render stdout', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
import colors from 'colors/safe'; import colors from 'colors/safe';
const { test } = pwt; import { test, expect } from '@playwright/test';
test('one', async ({}) => { test('one', async ({}) => {
console.log(colors.yellow('Hello world')); console.log(colors.yellow('Hello world'));
console.log('Hello again'); console.log('Hello again');
@ -118,7 +118,7 @@ test('should render stdout', async ({ runInlineTest }) => {
expect(testcase['system-out'][0]).not.toContain('u00'); expect(testcase['system-out'][0]).not.toContain('u00');
expect(testcase['system-err'][0]).toContain('My error'); expect(testcase['system-err'][0]).toContain('My error');
expect(testcase['system-err'][0]).not.toContain('\u0000'); // null control character expect(testcase['system-err'][0]).not.toContain('\u0000'); // null control character
expect(testcase['failure'][0]['_']).toContain(`> 12 | test.expect("abc").toBe('abcd');`); expect(testcase['failure'][0]['_']).toContain(`> 9 | test.expect("abc").toBe('abcd');`);
expect(result.exitCode).toBe(1); expect(result.exitCode).toBe(1);
}); });
@ -131,7 +131,7 @@ test('should render stdout without ansi escapes', async ({ runInlineTest }) => {
`, `,
'a.test.ts': ` 'a.test.ts': `
import colors from 'colors/safe'; import colors from 'colors/safe';
const { test } = pwt; import { test, expect } from '@playwright/test';
test('one', async ({}) => { test('one', async ({}) => {
console.log(colors.yellow('Hello world')); console.log(colors.yellow('Hello world'));
}); });
@ -152,7 +152,7 @@ test('should render, by default, character data as CDATA sections', async ({ run
}; };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('one', async ({}) => { test('one', async ({}) => {
process.stdout.write('Hello world &"\\'<>]]>'); process.stdout.write('Hello world &"\\'<>]]>');
}); });
@ -169,7 +169,7 @@ test('should render, by default, character data as CDATA sections', async ({ run
test('should render skipped', async ({ runInlineTest }) => { test('should render skipped', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('one', async () => { test('one', async () => {
console.log('Hello world'); console.log('Hello world');
}); });
@ -189,7 +189,7 @@ test('should render skipped', async ({ runInlineTest }) => {
test('should report skipped due to sharding', async ({ runInlineTest }) => { test('should report skipped due to sharding', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('one', async () => { test('one', async () => {
}); });
test('two', async () => { test('two', async () => {
@ -197,7 +197,7 @@ test('should report skipped due to sharding', async ({ runInlineTest }) => {
}); });
`, `,
'b.test.js': ` 'b.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('three', async () => { test('three', async () => {
}); });
test('four', async () => { test('four', async () => {
@ -221,7 +221,7 @@ test('should not render projects if they dont exist', async ({ runInlineTest })
module.exports = { }; module.exports = { };
`, `,
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('one', async ({}) => { test('one', async ({}) => {
expect(1).toBe(1); expect(1).toBe(1);
}); });
@ -247,7 +247,7 @@ test('should render projects', async ({ runInlineTest }) => {
module.exports = { projects: [ { name: 'project1' }, { name: 'project2' } ] }; module.exports = { projects: [ { name: 'project1' }, { name: 'project2' } ] };
`, `,
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('one', async ({}) => { test('one', async ({}) => {
expect(1).toBe(1); expect(1).toBe(1);
}); });
@ -277,7 +277,7 @@ test('should render projects', async ({ runInlineTest }) => {
test('should render existing attachments, but not missing ones', async ({ runInlineTest }) => { test('should render existing attachments, but not missing ones', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.use({ screenshot: 'on' }); test.use({ screenshot: 'on' });
test('one', async ({ page }, testInfo) => { test('one', async ({ page }, testInfo) => {
await page.setContent('hello'); await page.setContent('hello');
@ -309,7 +309,7 @@ function parseXML(xml: string): any {
test('should not render annotations to custom testcase properties by default', async ({ runInlineTest }) => { test('should not render annotations to custom testcase properties by default', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('one', async ({}, testInfo) => { test('one', async ({}, testInfo) => {
testInfo.annotations.push({ type: 'unknown_annotation', description: 'unknown' }); testInfo.annotations.push({ type: 'unknown_annotation', description: 'unknown' });
});2 });2
@ -333,7 +333,7 @@ test('should render text content based annotations to custom testcase properties
}; };
`, `,
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('one', async ({}, testInfo) => { test('one', async ({}, testInfo) => {
testInfo.annotations.push({ type: 'test_description', description: 'sample description' }); testInfo.annotations.push({ type: 'test_description', description: 'sample description' });
testInfo.annotations.push({ type: 'unknown_annotation', description: 'unknown' }); testInfo.annotations.push({ type: 'unknown_annotation', description: 'unknown' });
@ -362,7 +362,7 @@ test('should render all annotations to testcase value based properties, if reque
}; };
`, `,
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('one', async ({}, testInfo) => { test('one', async ({}, testInfo) => {
testInfo.annotations.push({ type: 'test_id', description: '1234' }); testInfo.annotations.push({ type: 'test_id', description: '1234' });
testInfo.annotations.push({ type: 'test_key', description: 'CALC-2' }); testInfo.annotations.push({ type: 'test_key', description: 'CALC-2' });
@ -397,7 +397,7 @@ test('should embed attachments to a custom testcase property, if explicitly requ
}; };
`, `,
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('one', async ({}, testInfo) => { test('one', async ({}, testInfo) => {
const file = testInfo.outputPath('evidence1.txt'); const file = testInfo.outputPath('evidence1.txt');
require('fs').writeFileSync(file, 'hello', 'utf8'); require('fs').writeFileSync(file, 'hello', 'utf8');
@ -428,7 +428,7 @@ test('should embed attachments to a custom testcase property, if explicitly requ
test('should not embed attachments to a custom testcase property, if not explicitly requested', async ({ runInlineTest }) => { test('should not embed attachments to a custom testcase property, if not explicitly requested', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('one', async ({}, testInfo) => { test('one', async ({}, testInfo) => {
const file = testInfo.outputPath('evidence1.txt'); const file = testInfo.outputPath('evidence1.txt');
require('fs').writeFileSync(file, 'hello', 'utf8'); require('fs').writeFileSync(file, 'hello', 'utf8');
@ -453,7 +453,7 @@ test.describe('report location', () => {
module.exports = { reporter: [['junit', { outputFile: '../my-report/a.xml' }]] }; module.exports = { reporter: [['junit', { outputFile: '../my-report/a.xml' }]] };
`, `,
'nested/project/a.test.js': ` 'nested/project/a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('one', async ({}) => { test('one', async ({}) => {
expect(1).toBe(1); expect(1).toBe(1);
}); });
@ -471,7 +471,7 @@ test.describe('report location', () => {
module.exports = { projects: [ {} ] }; module.exports = { projects: [ {} ] };
`, `,
'foo/bar/baz/tests/a.spec.js': ` 'foo/bar/baz/tests/a.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
const fs = require('fs'); const fs = require('fs');
test('pass', ({}, testInfo) => { test('pass', ({}, testInfo) => {
}); });

View File

@ -19,17 +19,17 @@ import { test, expect } from './playwright-test-fixtures';
test('render unexpected after retry', async ({ runInlineTest }) => { test('render unexpected after retry', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; const { test, expect } = require('@playwright/test');
test('one', async ({}) => { test('one', async ({}) => {
expect(1).toBe(0); expect(1).toBe(0);
}); });
`, `,
}, { retries: 3, reporter: 'line' }); }, { retries: 3, reporter: 'line' });
const text = result.output; const text = result.output;
expect(text).toContain('[1/1] a.test.js:6:7 one'); expect(text).toContain('[1/1] a.test.js:3:7 one');
expect(text).toContain('[2/1] (retries) a.test.js:6:7 one (retry #1)'); expect(text).toContain('[2/1] (retries) a.test.js:3:7 one (retry #1)');
expect(text).toContain('[3/1] (retries) a.test.js:6:7 one (retry #2)'); expect(text).toContain('[3/1] (retries) a.test.js:3:7 one (retry #2)');
expect(text).toContain('[4/1] (retries) a.test.js:6:7 one (retry #3)'); expect(text).toContain('[4/1] (retries) a.test.js:3:7 one (retry #3)');
expect(text).toContain('1 failed'); expect(text).toContain('1 failed');
expect(text).toContain('1) a.test'); expect(text).toContain('1) a.test');
expect(text).not.toContain('2) a.test'); expect(text).not.toContain('2) a.test');
@ -42,7 +42,7 @@ test('render unexpected after retry', async ({ runInlineTest }) => {
test('render flaky', async ({ runInlineTest }) => { test('render flaky', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('one', async ({}, testInfo) => { test('one', async ({}, testInfo) => {
expect(testInfo.retry).toBe(3); expect(testInfo.retry).toBe(3);
}); });
@ -56,7 +56,7 @@ test('render flaky', async ({ runInlineTest }) => {
test('should print flaky failures', async ({ runInlineTest }) => { test('should print flaky failures', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('foobar', async ({}, testInfo) => { test('foobar', async ({}, testInfo) => {
expect(testInfo.retry).toBe(1); expect(testInfo.retry).toBe(1);
}); });
@ -70,14 +70,14 @@ test('should print flaky failures', async ({ runInlineTest }) => {
test('should work on CI', async ({ runInlineTest }) => { test('should work on CI', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; const { test, expect } = require('@playwright/test');
test('one', async ({}) => { test('one', async ({}) => {
expect(1).toBe(0); expect(1).toBe(0);
}); });
`, `,
}, { reporter: 'line' }, { CI: '1' }); }, { reporter: 'line' }, { CI: '1' });
const text = result.output; const text = result.output;
expect(text).toContain('[1/1] a.test.js:6:7 one'); expect(text).toContain('[1/1] a.test.js:3:7 one');
expect(text).toContain('1 failed'); expect(text).toContain('1 failed');
expect(text).toContain('1) a.test'); expect(text).toContain('1) a.test');
expect(result.exitCode).toBe(1); expect(result.exitCode).toBe(1);
@ -86,7 +86,7 @@ test('should work on CI', async ({ runInlineTest }) => {
test('should print output', async ({ runInlineTest }) => { test('should print output', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('foobar', async ({}, testInfo) => { test('foobar', async ({}, testInfo) => {
process.stdout.write('one'); process.stdout.write('one');
process.stdout.write('two'); process.stdout.write('two');
@ -96,7 +96,7 @@ test('should print output', async ({ runInlineTest }) => {
}, { reporter: 'line' }); }, { reporter: 'line' });
expect(result.exitCode).toBe(0); expect(result.exitCode).toBe(0);
expect(result.output).toContain([ expect(result.output).toContain([
'a.spec.ts:6:7 foobar', 'a.spec.ts:3:11 foobar',
'one', 'one',
'', '',
'two', 'two',

View File

@ -29,7 +29,7 @@ test('render each test with project name', async ({ runInlineTest }) => {
] }; ] };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; const { test, expect } = require('@playwright/test');
test('fails', async ({}) => { test('fails', async ({}) => {
expect(1).toBe(0); expect(1).toBe(0);
}); });
@ -42,19 +42,19 @@ test('render each test with project name', async ({ runInlineTest }) => {
}, { reporter: 'list', workers: '1' }); }, { reporter: 'list', workers: '1' });
const text = result.output; const text = result.output;
expect(text).toContain(`${NEGATIVE_STATUS_MARK} 1 [foo] a.test.ts:6:7 fails`); expect(text).toContain(`${NEGATIVE_STATUS_MARK} 1 [foo] a.test.ts:3:7 fails`);
expect(text).toContain(`${POSITIVE_STATUS_MARK} 2 [foo] a.test.ts:9:7 passes`); expect(text).toContain(`${POSITIVE_STATUS_MARK} 2 [foo] a.test.ts:6:7 passes`);
expect(text).toContain(`- 3 [foo] a.test.ts:12:12 skipped`); expect(text).toContain(`- 3 [foo] a.test.ts:9:12 skipped`);
expect(text).toContain(`${NEGATIVE_STATUS_MARK} 4 [bar] a.test.ts:6:7 fails`); expect(text).toContain(`${NEGATIVE_STATUS_MARK} 4 [bar] a.test.ts:3:7 fails`);
expect(text).toContain(`${POSITIVE_STATUS_MARK} 5 [bar] a.test.ts:9:7 passes`); expect(text).toContain(`${POSITIVE_STATUS_MARK} 5 [bar] a.test.ts:6:7 passes`);
expect(text).toContain(`- 6 [bar] a.test.ts:12:12 skipped`); expect(text).toContain(`- 6 [bar] a.test.ts:9:12 skipped`);
expect(result.exitCode).toBe(1); expect(result.exitCode).toBe(1);
}); });
test('render steps', async ({ runInlineTest }) => { test('render steps', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('passes', async ({}) => { test('passes', async ({}) => {
await test.step('outer 1.0', async () => { await test.step('outer 1.0', async () => {
await test.step('inner 1.1', async () => {}); await test.step('inner 1.1', async () => {});
@ -71,7 +71,7 @@ test('render steps', async ({ runInlineTest }) => {
const lines = text.split('\n').filter(l => l.match(/^\d :/)).map(l => l.replace(/\d+ms/, 'Xms')); const lines = text.split('\n').filter(l => l.match(/^\d :/)).map(l => l.replace(/\d+ms/, 'Xms'));
lines.pop(); // Remove last item that contains [v] and time in ms. lines.pop(); // Remove last item that contains [v] and time in ms.
expect(lines).toEqual([ expect(lines).toEqual([
'0 : 1 a.test.ts:6:7 passes', '0 : 1 a.test.ts:3:11 passes',
'1 : 1.1 passes outer 1.0', '1 : 1.1 passes outer 1.0',
'2 : 1.2 passes outer 1.0 inner 1.1', '2 : 1.2 passes outer 1.0 inner 1.1',
'2 : 1.2 passes outer 1.0 inner 1.1 (Xms)', '2 : 1.2 passes outer 1.0 inner 1.1 (Xms)',
@ -90,7 +90,7 @@ test('render steps', async ({ runInlineTest }) => {
test('render steps inlint', async ({ runInlineTest }) => { test('render steps inlint', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('passes', async ({}) => { test('passes', async ({}) => {
await test.step('outer 1.0', async () => { await test.step('outer 1.0', async () => {
await test.step('inner 1.1', async () => {}); await test.step('inner 1.1', async () => {});
@ -107,19 +107,19 @@ test('render steps inlint', async ({ runInlineTest }) => {
const lines = text.split('\n').filter(l => l.match(/^\d :/)).map(l => l.replace(/\d+ms/, 'Xms')); const lines = text.split('\n').filter(l => l.match(/^\d :/)).map(l => l.replace(/\d+ms/, 'Xms'));
lines.pop(); // Remove last item that contains [v] and time in ms. lines.pop(); // Remove last item that contains [v] and time in ms.
expect(lines).toEqual([ expect(lines).toEqual([
'0 : 1 a.test.ts:6:7 passes', '0 : 1 a.test.ts:3:11 passes',
'0 : 1 a.test.ts:7:20 passes outer 1.0', '0 : 1 a.test.ts:4:20 passes outer 1.0',
'0 : 1 a.test.ts:8:22 passes outer 1.0 inner 1.1', '0 : 1 a.test.ts:5:22 passes outer 1.0 inner 1.1',
'0 : 1 a.test.ts:7:20 passes outer 1.0', '0 : 1 a.test.ts:4:20 passes outer 1.0',
'0 : 1 a.test.ts:9:22 passes outer 1.0 inner 1.2', '0 : 1 a.test.ts:6:22 passes outer 1.0 inner 1.2',
'0 : 1 a.test.ts:7:20 passes outer 1.0', '0 : 1 a.test.ts:4:20 passes outer 1.0',
'0 : 1 a.test.ts:6:7 passes', '0 : 1 a.test.ts:3:11 passes',
'0 : 1 a.test.ts:11:20 passes outer 2.0', '0 : 1 a.test.ts:8:20 passes outer 2.0',
'0 : 1 a.test.ts:12:22 passes outer 2.0 inner 2.1', '0 : 1 a.test.ts:9:22 passes outer 2.0 inner 2.1',
'0 : 1 a.test.ts:11:20 passes outer 2.0', '0 : 1 a.test.ts:8:20 passes outer 2.0',
'0 : 1 a.test.ts:13:22 passes outer 2.0 inner 2.2', '0 : 1 a.test.ts:10:22 passes outer 2.0 inner 2.2',
'0 : 1 a.test.ts:11:20 passes outer 2.0', '0 : 1 a.test.ts:8:20 passes outer 2.0',
'0 : 1 a.test.ts:6:7 passes', '0 : 1 a.test.ts:3:11 passes',
]); ]);
}); });
@ -127,7 +127,7 @@ test('very long console line should not mess terminal', async ({ runInlineTest }
const TTY_WIDTH = 80; const TTY_WIDTH = 80;
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('passes', async ({}) => { test('passes', async ({}) => {
console.log('a'.repeat(80) + 'b'.repeat(20)); console.log('a'.repeat(80) + 'b'.repeat(20));
}); });
@ -136,17 +136,17 @@ test('very long console line should not mess terminal', async ({ runInlineTest }
const renderedText = simpleAnsiRenderer(result.rawOutput, TTY_WIDTH); const renderedText = simpleAnsiRenderer(result.rawOutput, TTY_WIDTH);
if (process.platform === 'win32') if (process.platform === 'win32')
expect(renderedText).toContain(' ok 1 a.test.ts:6:7 passes'); expect(renderedText).toContain(' ok 1 a.test.ts:3:11 passes');
else else
expect(renderedText).toContain(' ✓ 1 a.test.ts:6:7 passes'); expect(renderedText).toContain(' ✓ 1 a.test.ts:3:11 passes');
expect(renderedText).not.toContain(' 1 a.test.ts:6:7 passes'); expect(renderedText).not.toContain(' 1 a.test.ts:3:11 passes');
expect(renderedText).toContain('a'.repeat(80) + '\n' + 'b'.repeat(20)); expect(renderedText).toContain('a'.repeat(80) + '\n' + 'b'.repeat(20));
}); });
test('render retries', async ({ runInlineTest }) => { test('render retries', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('flaky', async ({}, testInfo) => { test('flaky', async ({}, testInfo) => {
expect(testInfo.retry).toBe(1); expect(testInfo.retry).toBe(1);
}); });
@ -156,10 +156,10 @@ test('render retries', async ({ runInlineTest }) => {
const lines = text.split('\n').filter(l => l.startsWith('0 :') || l.startsWith('1 :')).map(l => l.replace(/\d+(\.\d+)?m?s/, 'XXms')); const lines = text.split('\n').filter(l => l.startsWith('0 :') || l.startsWith('1 :')).map(l => l.replace(/\d+(\.\d+)?m?s/, 'XXms'));
expect(lines).toEqual([ expect(lines).toEqual([
`0 : 1 a.test.ts:6:7 flaky`, `0 : 1 a.test.ts:3:11 flaky`,
`0 : ${NEGATIVE_STATUS_MARK} 1 a.test.ts:6:7 flaky (XXms)`, `0 : ${NEGATIVE_STATUS_MARK} 1 a.test.ts:3:11 flaky (XXms)`,
`1 : 2 a.test.ts:6:7 flaky (retry #1)`, `1 : 2 a.test.ts:3:11 flaky (retry #1)`,
`1 : ${POSITIVE_STATUS_MARK} 2 a.test.ts:6:7 flaky (retry #1) (XXms)`, `1 : ${POSITIVE_STATUS_MARK} 2 a.test.ts:3:11 flaky (retry #1) (XXms)`,
]); ]);
}); });
@ -171,7 +171,7 @@ test('should truncate long test names', async ({ runInlineTest }) => {
] }; ] };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('failure in very long name', async ({}) => { test('failure in very long name', async ({}) => {
expect(1).toBe(0); expect(1).toBe(0);
}); });
@ -188,25 +188,25 @@ test('should truncate long test names', async ({ runInlineTest }) => {
const lines = result.output.split('\n').slice(3, 11); const lines = result.output.split('\n').slice(3, 11);
expect(lines.every(line => line.length <= 50)).toBe(true); expect(lines.every(line => line.length <= 50)).toBe(true);
expect(lines[0]).toBe(` 1 … a.test.ts:6:7 failure in very long name`); expect(lines[0]).toBe(` 1 …a.test.ts:3:11 failure in very long name`);
expect(lines[1]).toContain(`${NEGATIVE_STATUS_MARK} 1 …`); expect(lines[1]).toContain(`${NEGATIVE_STATUS_MARK} 1 …`);
expect(lines[1]).toContain(`:6:7 failure in very long name (`); expect(lines[1]).toContain(`:3:11 failure in very long name (`);
expect(lines[1].length).toBe(50); expect(lines[1].length).toBe(50);
expect(lines[2]).toBe(` 2 [foo] a.test.ts:9:7 passes`); expect(lines[2]).toBe(` 2 [foo] a.test.ts:6:11 passes`);
expect(lines[3]).toContain(`${POSITIVE_STATUS_MARK} 2 [foo] a.test.ts:9:7 passes (`); expect(lines[3]).toContain(`${POSITIVE_STATUS_MARK} 2 [foo] a.test.ts:6:11 passes (`);
expect(lines[4]).toBe(` 3 [foo] a.test.ts:11:7 passes 2 long name`); expect(lines[4]).toBe(` 3 [foo] a.test.ts:8:11 passes 2 long name`);
expect(lines[5]).toContain(`${POSITIVE_STATUS_MARK} 3 …`); expect(lines[5]).toContain(`${POSITIVE_STATUS_MARK} 3 …`);
expect(lines[5]).toContain(`test.ts:11:7 passes 2 long name (`); expect(lines[5]).toContain(`test.ts:8:11 passes 2 long name (`);
expect(lines[5].length).toBe(50); expect(lines[5].length).toBe(50);
expect(lines[6]).toBe(` 4 …› a.test.ts:13:12 skipped very long name`); expect(lines[6]).toBe(` 4 …› a.test.ts:10:12 skipped very long name`);
expect(lines[7]).toBe(` - 4 …› a.test.ts:13:12 skipped very long name`); expect(lines[7]).toBe(` - 4 …› a.test.ts:10:12 skipped very long name`);
}); });
function simpleAnsiRenderer(text, ttyWidth) { function simpleAnsiRenderer(text, ttyWidth) {

View File

@ -23,7 +23,7 @@ const kRawReporterPath = path.join(__dirname, '..', '..', 'packages', 'playwrigh
test('should generate raw report', async ({ runInlineTest }, testInfo) => { test('should generate raw report', async ({ runInlineTest }, testInfo) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('passes', async ({ page }, testInfo) => {}); test('passes', async ({ page }, testInfo) => {});
`, `,
}, { reporter: 'dot,' + kRawReporterPath }, {}, { usesCustomOutputDir: true }); }, { reporter: 'dot,' + kRawReporterPath }, {}, { usesCustomOutputDir: true });
@ -44,7 +44,7 @@ test('should use project name', async ({ runInlineTest }, testInfo) => {
} }
`, `,
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('passes', async ({ page }, testInfo) => {}); test('passes', async ({ page }, testInfo) => {});
`, `,
}, { reporter: 'dot,' + kRawReporterPath }, {}, { usesCustomOutputDir: true }); }, { reporter: 'dot,' + kRawReporterPath }, {}, { usesCustomOutputDir: true });
@ -56,7 +56,7 @@ test('should use project name', async ({ runInlineTest }, testInfo) => {
test('should save stdio', async ({ runInlineTest }, testInfo) => { test('should save stdio', async ({ runInlineTest }, testInfo) => {
await runInlineTest({ await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('passes', async ({ page }, testInfo) => { test('passes', async ({ page }, testInfo) => {
console.log('STDOUT'); console.log('STDOUT');
process.stdout.write(Buffer.from([1, 2, 3])); process.stdout.write(Buffer.from([1, 2, 3]));
@ -86,7 +86,7 @@ test('should save stdio', async ({ runInlineTest }, testInfo) => {
test('should save attachments', async ({ runInlineTest }, testInfo) => { test('should save attachments', async ({ runInlineTest }, testInfo) => {
await runInlineTest({ await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('passes', async ({ page }, testInfo) => { test('passes', async ({ page }, testInfo) => {
testInfo.attachments.push({ testInfo.attachments.push({
name: 'binary', name: 'binary',
@ -115,7 +115,7 @@ test(`testInfo.attach should save attachments via path`, async ({ runInlineTest
'a.test.js': ` 'a.test.js': `
const path = require('path'); const path = require('path');
const fs = require('fs'); const fs = require('fs');
const { test } = pwt; import { test, expect } from '@playwright/test';
test('infer contentType from path', async ({}, testInfo) => { test('infer contentType from path', async ({}, testInfo) => {
const tmpPath = testInfo.outputPath('example.json'); const tmpPath = testInfo.outputPath('example.json');
await fs.promises.writeFile(tmpPath, 'We <3 Playwright!'); await fs.promises.writeFile(tmpPath, 'We <3 Playwright!');
@ -193,7 +193,7 @@ test(`testInfo.attach should save attachments via inline attachment`, async ({ r
'a.test.js': ` 'a.test.js': `
const path = require('path'); const path = require('path');
const fs = require('fs'); const fs = require('fs');
const { test } = pwt; import { test, expect } from '@playwright/test';
test('default contentType - string', async ({}, testInfo) => { test('default contentType - string', async ({}, testInfo) => {
await testInfo.attach('example.json', { body: 'We <3 Playwright!' }); await testInfo.attach('example.json', { body: 'We <3 Playwright!' });
}); });
@ -250,7 +250,7 @@ test('dupe project names', async ({ runInlineTest }, testInfo) => {
} }
`, `,
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('passes', async ({ page }, testInfo) => {}); test('passes', async ({ page }, testInfo) => {});
`, `,
}, { reporter: 'dot,' + kRawReporterPath }, {}, { usesCustomOutputDir: true }); }, { reporter: 'dot,' + kRawReporterPath }, {}, { usesCustomOutputDir: true });

View File

@ -122,7 +122,7 @@ test('should work with custom reporter', async ({ runInlineTest }) => {
}; };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('not run', async ({}) => { test('not run', async ({}) => {
console.log('log'); console.log('log');
console.error('error'); console.error('error');
@ -163,7 +163,7 @@ test('should work without a file extension', async ({ runInlineTest }) => {
}; };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async ({}) => { test('pass', async ({}) => {
}); });
` `
@ -191,7 +191,7 @@ test('should report onEnd after global teardown', async ({ runInlineTest }) => {
}; };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async ({}) => { test('pass', async ({}) => {
}); });
` `
@ -214,7 +214,7 @@ test('should load reporter from node_modules', async ({ runInlineTest }) => {
}; };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async ({}) => { test('pass', async ({}) => {
}); });
` `
@ -236,7 +236,7 @@ test('should report expect steps', async ({ runInlineTest }) => {
}; };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('fail', async ({}) => { test('fail', async ({}) => {
expect(true).toBeTruthy(); expect(true).toBeTruthy();
expect(false).toBeTruthy(); expect(false).toBeTruthy();
@ -288,7 +288,7 @@ test('should report api steps', async ({ runInlineTest }) => {
}; };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async ({ page, request }) => { test('pass', async ({ page, request }) => {
await Promise.all([ await Promise.all([
page.waitForNavigation(), page.waitForNavigation(),
@ -377,7 +377,7 @@ test('should report api step failure', async ({ runInlineTest }) => {
}; };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('fail', async ({ page }) => { test('fail', async ({ page }) => {
await page.setContent('<button></button>'); await page.setContent('<button></button>');
await page.click('input', { timeout: 1 }); await page.click('input', { timeout: 1 });
@ -405,7 +405,8 @@ test('should report api step failure', async ({ runInlineTest }) => {
test('should not have internal error when steps are finished after timeout', async ({ runInlineTest }) => { test('should not have internal error when steps are finished after timeout', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
page: async ({ page }, use) => { page: async ({ page }, use) => {
await use(page); await use(page);
// Timeout in fixture teardown that will resolve on browser.close. // Timeout in fixture teardown that will resolve on browser.close.
@ -433,7 +434,7 @@ test('should show nice stacks for locators', async ({ runInlineTest }) => {
}; };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async ({ page }) => { test('pass', async ({ page }) => {
await page.setContent('<button></button>'); await page.setContent('<button></button>');
const locator = page.locator('button'); const locator = page.locator('button');
@ -470,7 +471,8 @@ test('should report forbid-only error to reporter', async ({ runInlineTest }) =>
}; };
`, `,
'a.test.ts': ` 'a.test.ts': `
pwt.test.only('pass', () => {}); import { test, expect } from '@playwright/test';
test.only('pass', () => {});
` `
}, { 'reporter': '', 'forbid-only': true }); }, { 'reporter': '', 'forbid-only': true });
@ -524,7 +526,8 @@ test('should report global setup error to reporter', async ({ runInlineTest }) =
}; };
`, `,
'a.spec.js': ` 'a.spec.js': `
pwt.test('test', () => {}); const { test, expect } = require('@playwright/test');
test('test', () => {});
`, `,
}, { 'reporter': '' }); }, { 'reporter': '' });
@ -535,7 +538,7 @@ test('should report global setup error to reporter', async ({ runInlineTest }) =
test('should report correct tests/suites when using grep', async ({ runInlineTest }) => { test('should report correct tests/suites when using grep', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.js': ` 'a.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.describe('@foo', () => { test.describe('@foo', () => {
test('test1', async ({ }) => { test('test1', async ({ }) => {
@ -579,7 +582,7 @@ test('should use sourceMap-based file suite names', async ({ runInlineTest }) =>
}; };
`, `,
'a.spec.js': 'a.spec.js':
`var __create = Object.create;//@no-header `var __create = Object.create;
var __defProp = Object.defineProperty; var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames; var __getOwnPropNames = Object.getOwnPropertyNames;
@ -622,7 +625,8 @@ test('parallelIndex is presented in onTestEnd', async ({ runInlineTest }) => {
}; };
`, `,
'a.spec.js': ` 'a.spec.js': `
pwt.test('test', () => {}); const { test, expect } = require('@playwright/test');
test('test', () => {});
`, `,
}, { 'reporter': '', 'workers': 1 }); }, { 'reporter': '', 'workers': 1 });

View File

@ -40,21 +40,21 @@ test('should respect path resolver', async ({ runInlineTest }) => {
}`, }`,
'a.test.ts': ` 'a.test.ts': `
import { foo } from 'util/b'; import { foo } from 'util/b';
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test', ({}, testInfo) => { test('test', ({}, testInfo) => {
expect(testInfo.project.name).toBe(foo); expect(testInfo.project.name).toBe(foo);
}); });
`, `,
'b.test.ts': ` 'b.test.ts': `
import { foo } from 'util2/b'; import { foo } from 'util2/b';
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test', ({}, testInfo) => { test('test', ({}, testInfo) => {
expect(testInfo.project.name).toBe(foo); expect(testInfo.project.name).toBe(foo);
}); });
`, `,
'c.test.ts': ` 'c.test.ts': `
import { foo } from 'util3'; import { foo } from 'util3';
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test', ({}, testInfo) => { test('test', ({}, testInfo) => {
expect(testInfo.project.name).toBe(foo); expect(testInfo.project.name).toBe(foo);
}); });
@ -81,7 +81,7 @@ test('should respect path resolver', async ({ runInlineTest }) => {
import { foo } from 'parent-util/b'; import { foo } from 'parent-util/b';
// This import should pick up <root>/tsconfig through the helper // This import should pick up <root>/tsconfig through the helper
import { foo as foo2 } from '../helper'; import { foo as foo2 } from '../helper';
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test', ({}, testInfo) => { test('test', ({}, testInfo) => {
expect(testInfo.project.name).toBe(foo); expect(testInfo.project.name).toBe(foo);
expect(testInfo.project.name).toBe(foo2); expect(testInfo.project.name).toBe(foo2);
@ -115,14 +115,14 @@ test('should respect baseurl', async ({ runInlineTest }) => {
}`, }`,
'a.test.ts': ` 'a.test.ts': `
import { foo } from 'util/b'; import { foo } from 'util/b';
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test', ({}, testInfo) => { test('test', ({}, testInfo) => {
expect(testInfo.project.name).toBe(foo); expect(testInfo.project.name).toBe(foo);
}); });
`, `,
'b.test.ts': ` 'b.test.ts': `
import { foo } from 'util2'; import { foo } from 'util2';
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test', ({}, testInfo) => { test('test', ({}, testInfo) => {
expect(testInfo.project.name).toBe(foo); expect(testInfo.project.name).toBe(foo);
}); });
@ -152,7 +152,7 @@ test('should respect baseurl w/o paths', async ({ runInlineTest }) => {
'dir2/inner.spec.ts': ` 'dir2/inner.spec.ts': `
// This import should pick up ../foo/bar/util/b due to baseUrl. // This import should pick up ../foo/bar/util/b due to baseUrl.
import { foo } from 'foo/bar/util/b'; import { foo } from 'foo/bar/util/b';
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test', ({}, testInfo) => { test('test', ({}, testInfo) => {
expect(foo).toBe(42); expect(foo).toBe(42);
}); });
@ -191,7 +191,7 @@ test('should respect complex path resolver', async ({ runInlineTest }) => {
}`, }`,
'a.spec.ts': ` 'a.spec.ts': `
import { foo } from 'prefix-matchedstar'; import { foo } from 'prefix-matchedstar';
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test', ({}, testInfo) => { test('test', ({}, testInfo) => {
expect(testInfo.project.name).toBe(foo); expect(testInfo.project.name).toBe(foo);
}); });
@ -201,7 +201,7 @@ test('should respect complex path resolver', async ({ runInlineTest }) => {
`, `,
'b.spec.ts': ` 'b.spec.ts': `
import { foo } from 'prefix-matchedstar-suffix'; import { foo } from 'prefix-matchedstar-suffix';
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test', ({}, testInfo) => { test('test', ({}, testInfo) => {
expect(testInfo.project.name).toBe(foo); expect(testInfo.project.name).toBe(foo);
}); });
@ -211,7 +211,7 @@ test('should respect complex path resolver', async ({ runInlineTest }) => {
`, `,
'c.spec.ts': ` 'c.spec.ts': `
import { foo } from 'matchedstar-suffix'; import { foo } from 'matchedstar-suffix';
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test', ({}, testInfo) => { test('test', ({}, testInfo) => {
expect(testInfo.project.name).toBe(foo); expect(testInfo.project.name).toBe(foo);
}); });
@ -221,7 +221,7 @@ test('should respect complex path resolver', async ({ runInlineTest }) => {
`, `,
'd.spec.ts': ` 'd.spec.ts': `
import { foo } from 'no-star'; import { foo } from 'no-star';
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test', ({}, testInfo) => { test('test', ({}, testInfo) => {
expect(testInfo.project.name).toBe(foo); expect(testInfo.project.name).toBe(foo);
}); });
@ -231,7 +231,7 @@ test('should respect complex path resolver', async ({ runInlineTest }) => {
`, `,
'e.spec.ts': ` 'e.spec.ts': `
import { foo } from 'longest-prefix'; import { foo } from 'longest-prefix';
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test', ({}, testInfo) => { test('test', ({}, testInfo) => {
expect(testInfo.project.name).toBe(foo); expect(testInfo.project.name).toBe(foo);
}); });
@ -246,7 +246,7 @@ test('should respect complex path resolver', async ({ runInlineTest }) => {
`, `,
'f.spec.ts': ` 'f.spec.ts': `
import { foo } from 'barfoobar'; import { foo } from 'barfoobar';
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test', ({}, testInfo) => { test('test', ({}, testInfo) => {
expect(testInfo.project.name).toBe(foo); expect(testInfo.project.name).toBe(foo);
}); });
@ -256,7 +256,7 @@ test('should respect complex path resolver', async ({ runInlineTest }) => {
`, `,
'g.spec.ts': ` 'g.spec.ts': `
import { foo } from 'foo/[bar]'; import { foo } from 'foo/[bar]';
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test', ({}, testInfo) => { test('test', ({}, testInfo) => {
expect(testInfo.project.name).toBe(foo); expect(testInfo.project.name).toBe(foo);
}); });
@ -285,7 +285,7 @@ test('should not use baseurl for relative imports', async ({ runInlineTest }) =>
'frontend/playwright/tests/forms_cms_standard.spec.ts': ` 'frontend/playwright/tests/forms_cms_standard.spec.ts': `
// This relative import should not use baseUrl // This relative import should not use baseUrl
import { foo } from '../utils'; import { foo } from '../utils';
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test', ({}, testInfo) => { test('test', ({}, testInfo) => {
expect(foo).toBe(42); expect(foo).toBe(42);
}); });
@ -329,7 +329,7 @@ test('should not use baseurl for relative imports when dir with same name exists
// This absolute import should use baseUrl // This absolute import should use baseUrl
import { bar } from '.bar'; import { bar } from '.bar';
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test', ({}, testInfo) => { test('test', ({}, testInfo) => {
expect(foo).toBe(42); expect(foo).toBe(42);
expect(index).toBe(42); expect(index).toBe(42);
@ -358,7 +358,7 @@ test('should respect path resolver for JS files when allowJs', async ({ runInlin
}`, }`,
'a.test.js': ` 'a.test.js': `
const { foo } = require('util/b'); const { foo } = require('util/b');
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test', ({}, testInfo) => { test('test', ({}, testInfo) => {
expect(testInfo.project.name).toBe(foo); expect(testInfo.project.name).toBe(foo);
}); });
@ -385,7 +385,7 @@ test('should not respect path resolver for JS files w/o allowJS', async ({ runIn
}`, }`,
'a.test.js': ` 'a.test.js': `
const { foo } = require('util/b'); const { foo } = require('util/b');
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test', ({}, testInfo) => { test('test', ({}, testInfo) => {
expect(testInfo.project.name).toBe(foo); expect(testInfo.project.name).toBe(foo);
}); });
@ -412,14 +412,14 @@ test('should respect path resolver for JS and TS files from jsconfig.json', asyn
}`, }`,
'a.test.js': ` 'a.test.js': `
const { foo } = require('util/b'); const { foo } = require('util/b');
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test', ({}, testInfo) => { test('test', ({}, testInfo) => {
expect(testInfo.project.name).toBe(foo); expect(testInfo.project.name).toBe(foo);
}); });
`, `,
'b.test.ts': ` 'b.test.ts': `
import { foo } from 'util/b'; import { foo } from 'util/b';
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test', ({}, testInfo) => { test('test', ({}, testInfo) => {
expect(testInfo.project.name).toBe(foo); expect(testInfo.project.name).toBe(foo);
}); });

View File

@ -19,7 +19,7 @@ import { test, expect } from './playwright-test-fixtures';
test('should retry failures', async ({ runInlineTest }) => { test('should retry failures', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'retry-failures.spec.js': ` 'retry-failures.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('flake', async ({}, testInfo) => { test('flake', async ({}, testInfo) => {
// Passes on the second run. // Passes on the second run.
expect(testInfo.retry).toBe(1); expect(testInfo.retry).toBe(1);
@ -46,7 +46,7 @@ test('should retry based on config', async ({ runInlineTest }) => {
] }; ] };
`, `,
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}, testInfo) => { test('pass', ({}, testInfo) => {
// Passes on the third run. // Passes on the third run.
expect(testInfo.retry).toBe(2); expect(testInfo.retry).toBe(2);
@ -66,7 +66,7 @@ test('should retry based on test.describe.configure', async ({ runInlineTest })
module.exports = { retries: 2 }; module.exports = { retries: 2 };
`, `,
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.describe.configure({ retries: 1 }); test.describe.configure({ retries: 1 });
test('fail 1', ({}, testInfo) => { test('fail 1', ({}, testInfo) => {
console.log('%%fail1-' + testInfo.retry); console.log('%%fail1-' + testInfo.retry);
@ -74,7 +74,7 @@ test('should retry based on test.describe.configure', async ({ runInlineTest })
}); });
`, `,
'b.test.js': ` 'b.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('fail 4', ({}, testInfo) => { test('fail 4', ({}, testInfo) => {
console.log('%%fail4-' + testInfo.retry); console.log('%%fail4-' + testInfo.retry);
expect(1).toBe(2); expect(1).toBe(2);
@ -118,7 +118,7 @@ test('should retry based on test.describe.configure', async ({ runInlineTest })
test('should retry timeout', async ({ runInlineTest }) => { test('should retry timeout', async ({ runInlineTest }) => {
const { exitCode, passed, failed, output } = await runInlineTest({ const { exitCode, passed, failed, output } = await runInlineTest({
'one-timeout.spec.js': ` 'one-timeout.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('timeout', async () => { test('timeout', async () => {
await new Promise(f => setTimeout(f, 10000)); await new Promise(f => setTimeout(f, 10000));
}); });
@ -133,7 +133,7 @@ test('should retry timeout', async ({ runInlineTest }) => {
test('should fail on unexpected pass with retries', async ({ runInlineTest }) => { test('should fail on unexpected pass with retries', async ({ runInlineTest }) => {
const { exitCode, failed, output } = await runInlineTest({ const { exitCode, failed, output } = await runInlineTest({
'unexpected-pass.spec.js': ` 'unexpected-pass.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('succeeds', () => { test('succeeds', () => {
test.fail(); test.fail();
expect(1 + 1).toBe(2); expect(1 + 1).toBe(2);
@ -148,7 +148,7 @@ test('should fail on unexpected pass with retries', async ({ runInlineTest }) =>
test('should retry unexpected pass', async ({ runInlineTest }) => { test('should retry unexpected pass', async ({ runInlineTest }) => {
const { exitCode, passed, failed, output } = await runInlineTest({ const { exitCode, passed, failed, output } = await runInlineTest({
'unexpected-pass.spec.js': ` 'unexpected-pass.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('succeeds', () => { test('succeeds', () => {
test.fail(); test.fail();
expect(1 + 1).toBe(2); expect(1 + 1).toBe(2);
@ -164,7 +164,7 @@ test('should retry unexpected pass', async ({ runInlineTest }) => {
test('should not retry expected failure', async ({ runInlineTest }) => { test('should not retry expected failure', async ({ runInlineTest }) => {
const { exitCode, passed, failed, output } = await runInlineTest({ const { exitCode, passed, failed, output } = await runInlineTest({
'expected-failure.spec.js': ` 'expected-failure.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('fails', () => { test('fails', () => {
test.fail(); test.fail();
expect(1 + 1).toBe(3); expect(1 + 1).toBe(3);
@ -184,7 +184,7 @@ test('should not retry expected failure', async ({ runInlineTest }) => {
test('should retry unhandled rejection', async ({ runInlineTest }) => { test('should retry unhandled rejection', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'unhandled-rejection.spec.js': ` 'unhandled-rejection.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('unhandled rejection', async () => { test('unhandled rejection', async () => {
setTimeout(() => { setTimeout(() => {
throw new Error('Unhandled rejection in the test'); throw new Error('Unhandled rejection in the test');
@ -203,7 +203,7 @@ test('should retry unhandled rejection', async ({ runInlineTest }) => {
test('should retry beforeAll failure', async ({ runInlineTest }) => { test('should retry beforeAll failure', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.js': ` 'a.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.beforeAll(async () => { test.beforeAll(async () => {
throw new Error('BeforeAll is bugged!'); throw new Error('BeforeAll is bugged!');
}); });
@ -224,7 +224,8 @@ test('should retry beforeAll failure', async ({ runInlineTest }) => {
test('should retry worker fixture setup failure', async ({ runInlineTest }) => { test('should retry worker fixture setup failure', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'helper.ts': ` 'helper.ts': `
export const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
export const test = base.extend({
worker: [ async () => { worker: [ async () => {
throw new Error('worker setup is bugged!'); throw new Error('worker setup is bugged!');
}, { scope: 'worker' } ] }, { scope: 'worker' } ]

View File

@ -19,7 +19,7 @@ import { test, expect } from './playwright-test-fixtures';
test('it should not allow multiple tests with the same name per suite', async ({ runInlineTest }) => { test('it should not allow multiple tests with the same name per suite', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'tests/example.spec.js': ` 'tests/example.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.describe('suite', () => { test.describe('suite', () => {
test('i-am-a-duplicate', async () => {}); test('i-am-a-duplicate', async () => {});
}); });
@ -31,19 +31,19 @@ test('it should not allow multiple tests with the same name per suite', async ({
expect(result.exitCode).toBe(1); expect(result.exitCode).toBe(1);
expect(result.output).toContain(`Error: duplicate test title`); expect(result.output).toContain(`Error: duplicate test title`);
expect(result.output).toContain(`i-am-a-duplicate`); expect(result.output).toContain(`i-am-a-duplicate`);
expect(result.output).toContain(`tests${path.sep}example.spec.js:4`);
expect(result.output).toContain(`tests${path.sep}example.spec.js:7`); expect(result.output).toContain(`tests${path.sep}example.spec.js:7`);
expect(result.output).toContain(`tests${path.sep}example.spec.js:10`);
}); });
test('it should not allow multiple tests with the same name in multiple files', async ({ runInlineTest }) => { test('it should not allow multiple tests with the same name in multiple files', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'tests/example1.spec.js': ` 'tests/example1.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('i-am-a-duplicate', async () => {}); test('i-am-a-duplicate', async () => {});
test('i-am-a-duplicate', async () => {}); test('i-am-a-duplicate', async () => {});
`, `,
'tests/example2.spec.js': ` 'tests/example2.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('i-am-a-duplicate', async () => {}); test('i-am-a-duplicate', async () => {});
test('i-am-a-duplicate', async () => {}); test('i-am-a-duplicate', async () => {});
`, `,
@ -51,29 +51,29 @@ test('it should not allow multiple tests with the same name in multiple files',
expect(result.exitCode).toBe(1); expect(result.exitCode).toBe(1);
expect(result.output).toContain('Error: duplicate test title'); expect(result.output).toContain('Error: duplicate test title');
expect(result.output).toContain(`test('i-am-a-duplicate'`); expect(result.output).toContain(`test('i-am-a-duplicate'`);
expect(result.output).toContain(`tests${path.sep}example1.spec.js:6`); expect(result.output).toContain(`tests${path.sep}example1.spec.js:3`);
expect(result.output).toContain(`tests${path.sep}example1.spec.js:7`); expect(result.output).toContain(`tests${path.sep}example1.spec.js:4`);
expect(result.output).toContain(`tests${path.sep}example2.spec.js:6`); expect(result.output).toContain(`tests${path.sep}example2.spec.js:3`);
expect(result.output).toContain(`tests${path.sep}example2.spec.js:7`); expect(result.output).toContain(`tests${path.sep}example2.spec.js:4`);
}); });
test('it should not allow a focused test when forbid-only is used', async ({ runInlineTest }) => { test('it should not allow a focused test when forbid-only is used', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'tests/focused-test.spec.js': ` 'tests/focused-test.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.only('i-am-focused', async () => {}); test.only('i-am-focused', async () => {});
` `
}, { 'forbid-only': true }); }, { 'forbid-only': true });
expect(result.exitCode).toBe(1); expect(result.exitCode).toBe(1);
expect(result.output).toContain('Error: focused item found in the --forbid-only mode'); expect(result.output).toContain('Error: focused item found in the --forbid-only mode');
expect(result.output).toContain(`test.only('i-am-focused'`); expect(result.output).toContain(`test.only('i-am-focused'`);
expect(result.output).toContain(`tests${path.sep}focused-test.spec.js:6`); expect(result.output).toContain(`tests${path.sep}focused-test.spec.js:3`);
}); });
test('should continue with other tests after worker process suddenly exits', async ({ runInlineTest }) => { test('should continue with other tests after worker process suddenly exits', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.js': ` 'a.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('passed1', () => {}); test('passed1', () => {});
test('passed2', () => {}); test('passed2', () => {});
test('failed1', () => { process.exit(0); }); test('failed1', () => { process.exit(0); });
@ -93,7 +93,7 @@ test('sigint should stop workers', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.js': ` 'a.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('interrupted1', async () => { test('interrupted1', async () => {
console.log('\\n%%SEND-SIGINT%%1'); console.log('\\n%%SEND-SIGINT%%1');
await new Promise(f => setTimeout(f, 3000)); await new Promise(f => setTimeout(f, 3000));
@ -103,7 +103,7 @@ test('sigint should stop workers', async ({ runInlineTest }) => {
}); });
`, `,
'b.spec.js': ` 'b.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('interrupted2', async () => { test('interrupted2', async () => {
console.log('\\n%%SEND-SIGINT%%2'); console.log('\\n%%SEND-SIGINT%%2');
await new Promise(f => setTimeout(f, 3000)); await new Promise(f => setTimeout(f, 3000));
@ -137,7 +137,8 @@ test('sigint should stop workers', async ({ runInlineTest }) => {
test('should use the first occurring error when an unhandled exception was thrown', async ({ runInlineTest }) => { test('should use the first occurring error when an unhandled exception was thrown', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'unhandled-exception.spec.js': ` 'unhandled-exception.spec.js': `
const test = pwt.test.extend({ const { test: base, expect } = require('@playwright/test');
const test = base.extend({
context: async ({}, test) => { context: async ({}, test) => {
await test(123) await test(123)
let errorWasThrownPromiseResolve = () => {} let errorWasThrownPromiseResolve = () => {}
@ -167,8 +168,9 @@ test('worker interrupt should report errors', async ({ runInlineTest }) => {
test.skip(process.platform === 'win32', 'No sending SIGINT on Windows'); test.skip(process.platform === 'win32', 'No sending SIGINT on Windows');
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.js': ` 'a.spec.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
throwOnTeardown: async ({}, use) => { throwOnTeardown: async ({}, use) => {
let reject; let reject;
await use(new Promise((f, r) => reject = r)); await use(new Promise((f, r) => reject = r));
@ -192,7 +194,7 @@ test('worker interrupt should report errors', async ({ runInlineTest }) => {
test('should not stall when workers are available', async ({ runInlineTest }) => { test('should not stall when workers are available', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.js': ` 'a.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
const { writeFile, waitForFile } = require('./utils.js'); const { writeFile, waitForFile } = require('./utils.js');
test('fails-1', async ({}, testInfo) => { test('fails-1', async ({}, testInfo) => {
await waitForFile(testInfo, 'lockA'); await waitForFile(testInfo, 'lockA');
@ -207,7 +209,7 @@ test('should not stall when workers are available', async ({ runInlineTest }) =>
}); });
`, `,
'b.spec.js': ` 'b.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
const { writeFile, waitForFile } = require('./utils.js'); const { writeFile, waitForFile } = require('./utils.js');
test('passes-2', async ({}, testInfo) => { test('passes-2', async ({}, testInfo) => {
console.log('\\n%%passes-2-started'); console.log('\\n%%passes-2-started');
@ -258,7 +260,8 @@ test('should not stall when workers are available', async ({ runInlineTest }) =>
test('should teardown workers that are redundant', async ({ runInlineTest }) => { test('should teardown workers that are redundant', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'helper.js': ` 'helper.js': `
module.exports = pwt.test.extend({ const { test: base, expect } = require('@playwright/test');
module.exports = base.extend({
w: [async ({}, use) => { w: [async ({}, use) => {
console.log('\\n%%worker setup'); console.log('\\n%%worker setup');
await use('worker'); await use('worker');
@ -309,7 +312,7 @@ test('should not hang if test suites in worker are inconsistent with runner', as
}; };
`, `,
'a.spec.js': ` 'a.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
const { getNames } = require('./names'); const { getNames } = require('./names');
const names = getNames(); const names = getNames();
for (const index in names) { for (const index in names) {
@ -349,7 +352,7 @@ test('sigint should stop global setup', async ({ runInlineTest }) => {
}; };
`, `,
'a.spec.js': ` 'a.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test', async () => { }); test('test', async () => { });
`, `,
}, { 'workers': 1 }, {}, { sendSIGINTAfter: 1 }); }, { 'workers': 1 }, {}, { sendSIGINTAfter: 1 });
@ -390,7 +393,7 @@ test('sigint should stop plugins', async ({ runInlineTest }) => {
}; };
`, `,
'a.spec.js': ` 'a.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test', async () => { }); test('test', async () => { });
`, `,
}, { 'workers': 1 }, {}, { sendSIGINTAfter: 1 }); }, { 'workers': 1 }, {}, { sendSIGINTAfter: 1 });
@ -431,7 +434,7 @@ test('sigint should stop plugins 2', async ({ runInlineTest }) => {
module.exports = { _plugins }; module.exports = { _plugins };
`, `,
'a.spec.js': ` 'a.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test', async () => { }); test('test', async () => { });
`, `,
}, { 'workers': 1 }, {}, { sendSIGINTAfter: 1 }); }, { 'workers': 1 }, {}, { sendSIGINTAfter: 1 });
@ -447,7 +450,7 @@ test('sigint should stop plugins 2', async ({ runInlineTest }) => {
test('should not crash with duplicate titles and .only', async ({ runInlineTest }) => { test('should not crash with duplicate titles and .only', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'example.spec.ts': ` 'example.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('non unique title', () => { console.log('do not run me'); }); test('non unique title', () => { console.log('do not run me'); });
test.skip('non unique title', () => { console.log('do not run me'); }); test.skip('non unique title', () => { console.log('do not run me'); });
test.only('non unique title', () => { console.log('do run me'); }); test.only('non unique title', () => { console.log('do run me'); });
@ -458,37 +461,37 @@ test('should not crash with duplicate titles and .only', async ({ runInlineTest
expect(result.output).toContain(`test('non unique title'`); expect(result.output).toContain(`test('non unique title'`);
expect(result.output).toContain(`test.skip('non unique title'`); expect(result.output).toContain(`test.skip('non unique title'`);
expect(result.output).toContain(`test.only('non unique title'`); expect(result.output).toContain(`test.only('non unique title'`);
expect(result.output).toContain(`example.spec.ts:6`); expect(result.output).toContain(`example.spec.ts:3`);
expect(result.output).toContain(`example.spec.ts:7`); expect(result.output).toContain(`example.spec.ts:4`);
expect(result.output).toContain(`example.spec.ts:8`); expect(result.output).toContain(`example.spec.ts:5`);
}); });
test('should not crash with duplicate titles and line filter', async ({ runInlineTest }) => { test('should not crash with duplicate titles and line filter', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'example.spec.ts': ` 'example.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('non unique title', () => { console.log('do not run me'); }); test('non unique title', () => { console.log('do not run me'); });
test.skip('non unique title', () => { console.log('do not run me'); }); test.skip('non unique title', () => { console.log('do not run me'); });
test('non unique title', () => { console.log('do run me'); }); test('non unique title', () => { console.log('do run me'); });
` `
}, {}, {}, { additionalArgs: ['example.spec.ts:8'] }); }, {}, {}, { additionalArgs: ['example.spec.ts:6'] });
expect(result.exitCode).toBe(1); expect(result.exitCode).toBe(1);
expect(result.output).toContain(`Error: duplicate test title`); expect(result.output).toContain(`Error: duplicate test title`);
expect(result.output).toContain(`test('non unique title'`); expect(result.output).toContain(`test('non unique title'`);
expect(result.output).toContain(`example.spec.ts:6`); expect(result.output).toContain(`example.spec.ts:3`);
expect(result.output).toContain(`example.spec.ts:7`); expect(result.output).toContain(`example.spec.ts:4`);
expect(result.output).toContain(`example.spec.ts:8`); expect(result.output).toContain(`example.spec.ts:5`);
}); });
test('should not load tests not matching filter', async ({ runInlineTest }) => { test('should not load tests not matching filter', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
console.log('in a.spec.ts'); console.log('in a.spec.ts');
test('test1', () => {}); test('test1', () => {});
`, `,
'example.spec.ts': ` 'example.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
console.log('in example.spec.ts'); console.log('in example.spec.ts');
test('test2', () => {}); test('test2', () => {});
` `

View File

@ -18,8 +18,9 @@ import { test, expect } from './playwright-test-fixtures';
const tests = { const tests = {
'helper.ts': ` 'helper.ts': `
export const headlessTest = pwt.test.extend({ headless: false }); import { test as base, expect } from '@playwright/test';
export const headedTest = pwt.test.extend({ headless: true }); export const headlessTest = base.extend({ headless: false });
export const headedTest = base.extend({ headless: true });
`, `,
'a1.spec.ts': ` 'a1.spec.ts': `
import { headlessTest, headedTest } from './helper'; import { headlessTest, headedTest } from './helper';

View File

@ -24,9 +24,10 @@ async function getSnapshotPaths(runInlineTest, testInfo, playwrightConfig, pathA
'playwright.config.js': ` 'playwright.config.js': `
module.exports = ${JSON.stringify(playwrightConfig, null, 2)} module.exports = ${JSON.stringify(playwrightConfig, null, 2)}
`, `,
'a/b/c/d.spec.js': ` 'a/b/c/d.spec.ts': `
pwt.test.describe('suite', () => { import { test, expect } from '@playwright/test';
pwt.test('test should work', async ({ page }, testInfo) => { test.describe('suite', () => {
test('test should work', async ({ page }, testInfo) => {
console.log([ console.log([
${JSON.stringify(SEPARATOR)}, ${JSON.stringify(SEPARATOR)},
testInfo.project.name, testInfo.project.name,
@ -98,8 +99,8 @@ test('tokens should expand property', async ({ runInlineTest }, testInfo) => {
expect.soft(snapshotPath['extension']).toBe('mysnapshot.png'); expect.soft(snapshotPath['extension']).toBe('mysnapshot.png');
expect.soft(snapshotPath['arg']).toBe(path.join('bar', 'foo')); expect.soft(snapshotPath['arg']).toBe(path.join('bar', 'foo'));
expect.soft(snapshotPath['testFileDir']).toBe(path.join('a', 'b', 'c')); expect.soft(snapshotPath['testFileDir']).toBe(path.join('a', 'b', 'c'));
expect.soft(snapshotPath['testFilePath']).toBe(path.join('a', 'b', 'c', 'd.spec.js')); expect.soft(snapshotPath['testFilePath']).toBe(path.join('a', 'b', 'c', 'd.spec.ts'));
expect.soft(snapshotPath['testFileName']).toBe('d.spec.js'); expect.soft(snapshotPath['testFileName']).toBe('d.spec.ts');
expect.soft(snapshotPath['snapshotDir']).toBe('a-snapshot-dir.png'); expect.soft(snapshotPath['snapshotDir']).toBe('a-snapshot-dir.png');
expect.soft(snapshotPath['snapshotSuffix']).toBe('-' + process.platform); expect.soft(snapshotPath['snapshotSuffix']).toBe('-' + process.platform);
expect.soft(snapshotPath['testName']).toBe('suite-test-should-work'); expect.soft(snapshotPath['testName']).toBe('suite-test-should-work');
@ -122,8 +123,9 @@ test('arg should receive default arg', async ({ runInlineTest }, testInfo) => {
snapshotPathTemplate: '__screenshots__/{arg}{ext}', snapshotPathTemplate: '__screenshots__/{arg}{ext}',
} }
`, `,
'a.spec.js': ` 'a.spec.ts': `
pwt.test('is a test', async ({ page }) => { import { test, expect } from '@playwright/test';
test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot(); await expect(page).toHaveScreenshot();
}); });
` `

View File

@ -19,7 +19,7 @@ import { test, expect } from './playwright-test-fixtures';
test('should get top level stdio', async ({ runInlineTest }) => { test('should get top level stdio', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.js': ` 'a.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
console.log('\\n%% top level stdout'); console.log('\\n%% top level stdout');
console.error('\\n%% top level stderr'); console.error('\\n%% top level stderr');
test('is a test', () => { test('is a test', () => {
@ -42,7 +42,8 @@ test('should get top level stdio', async ({ runInlineTest }) => {
test('should get stdio from worker fixture teardown', async ({ runInlineTest }) => { test('should get stdio from worker fixture teardown', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'helper.ts': ` 'helper.ts': `
export const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
export const test = base.extend({
fixture: [ async ({}, run) => { fixture: [ async ({}, run) => {
console.log('\\n%% worker setup'); console.log('\\n%% worker setup');
await run(); await run();
@ -67,7 +68,7 @@ test('should ignore stdio when quiet', async ({ runInlineTest }) => {
module.exports = { quiet: true }; module.exports = { quiet: true };
`, `,
'a.spec.js': ` 'a.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('is a test', () => { test('is a test', () => {
console.log('\\n%% stdout in a test'); console.log('\\n%% stdout in a test');
console.error('\\n%% stderr in a test'); console.error('\\n%% stderr in a test');
@ -80,7 +81,7 @@ test('should ignore stdio when quiet', async ({ runInlineTest }) => {
test('should support console colors', async ({ runInlineTest }) => { test('should support console colors', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.js': ` 'a.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('console log', () => { test('console log', () => {
console.log('process.stdout.isTTY = ' + process.stdout.isTTY); console.log('process.stdout.isTTY = ' + process.stdout.isTTY);
console.log('process.stderr.isTTY = ' + process.stderr.isTTY); console.log('process.stderr.isTTY = ' + process.stderr.isTTY);
@ -99,7 +100,7 @@ test('should support console colors', async ({ runInlineTest }) => {
test('should override hasColors and getColorDepth', async ({ runInlineTest }) => { test('should override hasColors and getColorDepth', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.js': ` 'a.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('console log', () => { test('console log', () => {
console.log('process.stdout.hasColors(1) = ' + process.stdout.hasColors(1)); console.log('process.stdout.hasColors(1) = ' + process.stdout.hasColors(1));
console.log('process.stderr.hasColors(1) = ' + process.stderr.hasColors(1)); console.log('process.stderr.hasColors(1) = ' + process.stderr.hasColors(1));
@ -117,7 +118,7 @@ test('should override hasColors and getColorDepth', async ({ runInlineTest }) =>
test('should not throw type error when using assert', async ({ runInlineTest }) => { test('should not throw type error when using assert', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.js': ` 'a.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
const assert = require('assert'); const assert = require('assert');
test('assert no type error', () => { test('assert no type error', () => {
assert.strictEqual(1, 2); assert.strictEqual(1, 2);

View File

@ -24,7 +24,7 @@ test('should provide store fixture', async ({ runInlineTest }) => {
module.exports = {}; module.exports = {};
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test, store } = pwt; import { test, store, expect } from '@playwright/test';
test('should store number', async ({ }) => { test('should store number', async ({ }) => {
expect(store).toBeTruthy(); expect(store).toBeTruthy();
expect(await store.get('number')).toBe(undefined); expect(await store.get('number')).toBe(undefined);
@ -56,7 +56,7 @@ test('should share store state between project setup and tests', async ({ runInl
}; };
`, `,
'store.setup.ts': ` 'store.setup.ts': `
const { test, expect, store } = pwt; import { test, store, expect } from '@playwright/test';
test.projectSetup('should initialize store', async ({ }) => { test.projectSetup('should initialize store', async ({ }) => {
expect(await store.get('number')).toBe(undefined); expect(await store.get('number')).toBe(undefined);
await store.set('number', 2022) await store.set('number', 2022)
@ -68,14 +68,14 @@ test('should share store state between project setup and tests', async ({ runInl
}); });
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test, store } = pwt; import { test, store, expect } from '@playwright/test';
test('should get data from setup', async ({ }) => { test('should get data from setup', async ({ }) => {
expect(await store.get('number')).toBe(2022); expect(await store.get('number')).toBe(2022);
expect(await store.get('object')).toEqual({ 'a': 2022 }); expect(await store.get('object')).toEqual({ 'a': 2022 });
}); });
`, `,
'b.test.ts': ` 'b.test.ts': `
const { test, store } = pwt; import { test, store, expect } from '@playwright/test';
test('should get data from setup', async ({ }) => { test('should get data from setup', async ({ }) => {
expect(await store.get('number')).toBe(2022); expect(await store.get('number')).toBe(2022);
expect(await store.get('object')).toEqual({ 'a': 2022 }); expect(await store.get('object')).toEqual({ 'a': 2022 });
@ -92,7 +92,7 @@ test('should persist store state between project runs', async ({ runInlineTest }
module.exports = { }; module.exports = { };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test, store } = pwt; import { test, store, expect } from '@playwright/test';
test('should have no data on first run', async ({ }) => { test('should have no data on first run', async ({ }) => {
expect(await store.get('number')).toBe(undefined); expect(await store.get('number')).toBe(undefined);
await store.set('number', 2022) await store.set('number', 2022)
@ -101,7 +101,7 @@ test('should persist store state between project runs', async ({ runInlineTest }
}); });
`, `,
'b.test.ts': ` 'b.test.ts': `
const { test, store } = pwt; import { test, store, expect } from '@playwright/test';
test('should get data from previous run', async ({ }) => { test('should get data from previous run', async ({ }) => {
expect(await store.get('number')).toBe(2022); expect(await store.get('number')).toBe(2022);
expect(await store.get('object')).toEqual({ 'a': 2022 }); expect(await store.get('object')).toEqual({ 'a': 2022 });
@ -137,7 +137,7 @@ test('should isolate store state between projects', async ({ runInlineTest }) =>
}; };
`, `,
'store.setup.ts': ` 'store.setup.ts': `
const { test, expect, store } = pwt; import { test, store, expect } from '@playwright/test';
test.projectSetup('should initialize store', async ({ }) => { test.projectSetup('should initialize store', async ({ }) => {
expect(await store.get('number')).toBe(undefined); expect(await store.get('number')).toBe(undefined);
await store.set('number', 2022) await store.set('number', 2022)
@ -149,14 +149,14 @@ test('should isolate store state between projects', async ({ runInlineTest }) =>
}); });
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test, store } = pwt; import { test, store, expect } from '@playwright/test';
test('should get data from setup', async ({ }) => { test('should get data from setup', async ({ }) => {
expect(await store.get('number')).toBe(2022); expect(await store.get('number')).toBe(2022);
expect(await store.get('name')).toBe('str-' + test.info().project.name); expect(await store.get('name')).toBe('str-' + test.info().project.name);
}); });
`, `,
'b.test.ts': ` 'b.test.ts': `
const { test, store } = pwt; import { test, store, expect } from '@playwright/test';
test('should get data from setup', async ({ }) => { test('should get data from setup', async ({ }) => {
expect(await store.get('number')).toBe(2022); expect(await store.get('number')).toBe(2022);
expect(await store.get('name')).toBe('str-' + test.info().project.name); expect(await store.get('name')).toBe('str-' + test.info().project.name);
@ -184,7 +184,7 @@ test('should load context storageState from store', async ({ runInlineTest, serv
}; };
`, `,
'store.setup.ts': ` 'store.setup.ts': `
const { test, expect, store } = pwt; import { test, store, expect } from '@playwright/test';
test.projectSetup('should save storageState', async ({ page, context }) => { test.projectSetup('should save storageState', async ({ page, context }) => {
expect(await store.get('user')).toBe(undefined); expect(await store.get('user')).toBe(undefined);
await page.goto('${server.PREFIX}/setcookie.html'); await page.goto('${server.PREFIX}/setcookie.html');
@ -193,7 +193,7 @@ test('should load context storageState from store', async ({ runInlineTest, serv
}); });
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.use({ test.use({
storageStateName: 'user' storageStateName: 'user'
}) })
@ -204,7 +204,7 @@ test('should load context storageState from store', async ({ runInlineTest, serv
}); });
`, `,
'b.test.ts': ` 'b.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('should not get data from setup if not configured', async ({ page }) => { test('should not get data from setup if not configured', async ({ page }) => {
await page.goto('${server.EMPTY_PAGE}'); await page.goto('${server.EMPTY_PAGE}');
const cookies = await page.evaluate(() => document.cookie); const cookies = await page.evaluate(() => document.cookie);
@ -236,7 +236,7 @@ test('should load storageStateName specified in the project config from store',
}; };
`, `,
'store.setup.ts': ` 'store.setup.ts': `
const { test, expect, store } = pwt; import { test, store, expect } from '@playwright/test';
test.use({ test.use({
storageStateName: ({}, use) => use(undefined), storageStateName: ({}, use) => use(undefined),
}) })
@ -248,7 +248,7 @@ test('should load storageStateName specified in the project config from store',
}); });
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('should get data from setup', async ({ page }) => { test('should get data from setup', async ({ page }) => {
await page.goto('${server.EMPTY_PAGE}'); await page.goto('${server.EMPTY_PAGE}');
const cookies = await page.evaluate(() => document.cookie); const cookies = await page.evaluate(() => document.cookie);
@ -280,7 +280,7 @@ test('should load storageStateName specified in the global config from store', a
}; };
`, `,
'store.setup.ts': ` 'store.setup.ts': `
const { test, expect, store } = pwt; import { test, store, expect } from '@playwright/test';
test.use({ test.use({
storageStateName: ({}, use) => use(undefined), storageStateName: ({}, use) => use(undefined),
}) })
@ -292,7 +292,7 @@ test('should load storageStateName specified in the global config from store', a
}); });
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('should get data from setup', async ({ page }) => { test('should get data from setup', async ({ page }) => {
await page.goto('${server.EMPTY_PAGE}'); await page.goto('${server.EMPTY_PAGE}');
const cookies = await page.evaluate(() => document.cookie); const cookies = await page.evaluate(() => document.cookie);
@ -319,7 +319,7 @@ test('should throw on unknown storageStateName value', async ({ runInlineTest, s
}; };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('should fail to initialize page', async ({ page }) => { test('should fail to initialize page', async ({ page }) => {
}); });
`, `,

View File

@ -19,6 +19,7 @@ import { test, expect } from './playwright-test-fixtures';
test('test.extend should work', async ({ runInlineTest }) => { test('test.extend should work', async ({ runInlineTest }) => {
const { output, passed } = await runInlineTest({ const { output, passed } = await runInlineTest({
'helper.ts': ` 'helper.ts': `
import { test, expect } from '@playwright/test';
global.logs = []; global.logs = [];
function createDerivedFixtures(suffix) { function createDerivedFixtures(suffix) {
@ -39,7 +40,7 @@ test('test.extend should work', async ({ runInlineTest }) => {
}; };
} }
export const base = pwt.test.extend({ export const base = test.extend({
suffix: ['', { scope: 'worker', option: true } ], suffix: ['', { scope: 'worker', option: true } ],
baseWorker: [async ({ suffix }, run) => { baseWorker: [async ({ suffix }, run) => {
global.logs.push('beforeAll-' + suffix); global.logs.push('beforeAll-' + suffix);
@ -128,8 +129,9 @@ test('config should override options but not fixtures', async ({ runInlineTest }
use: { param: 'config' }, use: { param: 'config' },
}; };
`, `,
'a.test.js': ` 'a.test.ts': `
const test1 = pwt.test.extend({ param: [ 'default', { option: true } ] }); import { test as base, expect } from '@playwright/test';
const test1 = base.extend({ param: [ 'default', { option: true } ] });
test1('default', async ({ param }) => { test1('default', async ({ param }) => {
console.log('default-' + param); console.log('default-' + param);
}); });
@ -165,8 +167,9 @@ test('test.extend should be able to merge', async ({ runInlineTest }) => {
use: { param: 'from-config' }, use: { param: 'from-config' },
}; };
`, `,
'a.test.js': ` 'a.test.ts': `
const base = pwt.test.extend({ import { test, expect } from '@playwright/test';
const base = test.extend({
myFixture: 'abc', myFixture: 'abc',
}); });
@ -201,9 +204,10 @@ test('test.extend should be able to merge', async ({ runInlineTest }) => {
test('test.extend should print nice message when used as _extendTest', async ({ runInlineTest }) => { test('test.extend should print nice message when used as _extendTest', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.ts': `
const test1 = pwt.test.extend({}); import { test as base, expect } from '@playwright/test';
const test2 = pwt.test.extend({}); const test1 = base.extend({});
const test2 = base.extend({});
const test3 = test1.extend(test2); const test3 = test1.extend(test2);
test3('test', () => {}); test3('test', () => {});
@ -216,8 +220,9 @@ test('test.extend should print nice message when used as _extendTest', async ({
test('test._extendTest should print nice message when used as extend', async ({ runInlineTest }) => { test('test._extendTest should print nice message when used as extend', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.ts': `
const test3 = pwt.test._extendTest({}); import { test as base, expect } from '@playwright/test';
const test3 = base._extendTest({});
test3('test', () => {}); test3('test', () => {});
`, `,
}); });
@ -233,8 +238,9 @@ test('test.use() with undefined should not be ignored', async ({ runInlineTest }
use: { option1: 'config' }, use: { option1: 'config' },
}; };
`, `,
'a.test.js': ` 'a.test.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
option1: [ 'default', { option: true } ], option1: [ 'default', { option: true } ],
option2: [ 'default', { option: true } ], option2: [ 'default', { option: true } ],
}); });
@ -284,8 +290,9 @@ test('undefined values in config and test.use should be reverted to default', as
use: { option1: undefined, option2: undefined }, use: { option1: undefined, option2: undefined },
}; };
`, `,
'a.test.js': ` 'a.test.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
option1: [ 'default1', { option: true } ], option1: [ 'default1', { option: true } ],
option2: [ 'default2', { option: true } ], option2: [ 'default2', { option: true } ],
option3: [ 'default3', { option: true } ], option3: [ 'default3', { option: true } ],

View File

@ -22,7 +22,7 @@ test('config.grep should work', async ({ runInlineTest }) => {
module.exports = { grep: /test1/ }; module.exports = { grep: /test1/ };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test1', async () => { console.log('\\n%% test1'); }); test('test1', async () => { console.log('\\n%% test1'); });
test('test2', async () => { console.log('\\n%% test2'); }); test('test2', async () => { console.log('\\n%% test2'); });
`, `,
@ -38,7 +38,7 @@ test('config.grepInvert should work', async ({ runInlineTest }) => {
module.exports = { grepInvert: /test1/ }; module.exports = { grepInvert: /test1/ };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test1', async () => { console.log('\\n%% test1'); }); test('test1', async () => { console.log('\\n%% test1'); });
test('test2', async () => { console.log('\\n%% test2'); }); test('test2', async () => { console.log('\\n%% test2'); });
`, `,
@ -54,7 +54,7 @@ test('project.grep should work', async ({ runInlineTest }) => {
module.exports = { projects: [ { grep: /test1/ } ] }; module.exports = { projects: [ { grep: /test1/ } ] };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test1', async () => { console.log('\\n%% test1'); }); test('test1', async () => { console.log('\\n%% test1'); });
test('test2', async () => { console.log('\\n%% test2'); }); test('test2', async () => { console.log('\\n%% test2'); });
`, `,
@ -70,7 +70,7 @@ test('project.grepInvert should work', async ({ runInlineTest }) => {
module.exports = { projects: [ { grepInvert: /test1/ } ] }; module.exports = { projects: [ { grepInvert: /test1/ } ] };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test1', async () => { console.log('\\n%% test1'); }); test('test1', async () => { console.log('\\n%% test1'); });
test('test2', async () => { console.log('\\n%% test2'); }); test('test2', async () => { console.log('\\n%% test2'); });
`, `,
@ -86,7 +86,7 @@ test('config.grep should intercect with --grep and --grepInvert', async ({ runIn
module.exports = { grep: /test./, grepInvert: /test4/ }; module.exports = { grep: /test./, grepInvert: /test4/ };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test1', async () => { console.log('\\n%% test1'); }); test('test1', async () => { console.log('\\n%% test1'); });
test('test2', async () => { console.log('\\n%% test2'); }); test('test2', async () => { console.log('\\n%% test2'); });
test('test3', async () => { console.log('\\n%% test3'); }); test('test3', async () => { console.log('\\n%% test3'); });

View File

@ -19,15 +19,15 @@ import * as path from 'path';
const tests = { const tests = {
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
`, `,
'b.test.ts': ` 'b.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
`, `,
'c.test.ts': ` 'c.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
` `
}; };
@ -55,19 +55,19 @@ test('should ignore a folder', async ({ runInlineTest }) => {
module.exports = { testIgnore: 'folder/**' }; module.exports = { testIgnore: 'folder/**' };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
`, `,
'folder/a.test.ts': ` 'folder/a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
`, `,
'folder/b.test.ts': ` 'folder/b.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
`, `,
'folder/c.test.ts': ` 'folder/c.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
` `
}); });
@ -78,19 +78,19 @@ test('should ignore a folder', async ({ runInlineTest }) => {
test('should ignore a node_modules', async ({ runInlineTest }) => { test('should ignore a node_modules', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
`, `,
'node_modules/a.test.ts': ` 'node_modules/a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
`, `,
'node_modules/b.test.ts': ` 'node_modules/b.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
`, `,
'folder/c.test.ts': ` 'folder/c.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
` `
}); });
@ -126,15 +126,15 @@ test('should use an array for testMatch', async ({ runInlineTest }) => {
module.exports = { testMatch: ['b.test.ts', /\\${path.sep}a.[tes]{4}.TS$/i] }; module.exports = { testMatch: ['b.test.ts', /\\${path.sep}a.[tes]{4}.TS$/i] };
`, `,
'dir/a.test.ts': ` 'dir/a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
`, `,
'b.test.ts': ` 'b.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
`, `,
'c.test.ts': ` 'c.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
` `
}); });
@ -150,15 +150,15 @@ test('should match absolute path', async ({ runInlineTest }) => {
module.exports = { testDir: path.join(__dirname, 'dir'), testMatch: /dir\\${path.sep}a/ }; module.exports = { testDir: path.join(__dirname, 'dir'), testMatch: /dir\\${path.sep}a/ };
`, `,
'dir/a.test.ts': ` 'dir/a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
`, `,
'dir/b.test.ts': ` 'dir/b.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
` `
}); });
@ -174,15 +174,15 @@ test('should match cli string argument', async ({ runInlineTest }) => {
module.exports = { testDir: path.join(__dirname, 'dir') }; module.exports = { testDir: path.join(__dirname, 'dir') };
`, `,
'dir/a.test.ts': ` 'dir/a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
`, `,
'dir/b.test.ts': ` 'dir/b.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
` `
}, {}, {}, { additionalArgs: [`dir\\${path.sep}a`] }); }, {}, {}, { additionalArgs: [`dir\\${path.sep}a`] });
@ -194,15 +194,15 @@ test('should match cli string argument', async ({ runInlineTest }) => {
test('should match regex string argument', async ({ runInlineTest }) => { test('should match regex string argument', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'dir/filea.test.ts': ` 'dir/filea.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
`, `,
'dir/fileb.test.ts': ` 'dir/fileb.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
`, `,
'filea.test.ts': ` 'filea.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
` `
}, {}, {}, { additionalArgs: ['/filea.*ts/'] }); }, {}, {}, { additionalArgs: ['/filea.*ts/'] });
@ -215,11 +215,11 @@ test('should match regex string with a colon argument', async ({ runInlineTest }
test.skip(process.platform === 'win32', 'Windows does not support colons in the file name'); test.skip(process.platform === 'win32', 'Windows does not support colons in the file name');
const result = await runInlineTest({ const result = await runInlineTest({
'fileb.test.ts': ` 'fileb.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
`, `,
'weird:file.test.ts': ` 'weird:file.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
` `
}, {}, {}, { additionalArgs: ['/weird:file\.test\.ts/'] }); }, {}, {}, { additionalArgs: ['/weird:file\.test\.ts/'] });
@ -231,15 +231,15 @@ test('should match regex string with a colon argument', async ({ runInlineTest }
test('should match case insensitive', async ({ runInlineTest }) => { test('should match case insensitive', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'capital/A.test.ts': ` 'capital/A.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
`, `,
'lowercase/a.test.ts': ` 'lowercase/a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
`, `,
'b.test.ts': ` 'b.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
` `
}, {}, {}, { additionalArgs: ['a.test.ts'] }); }, {}, {}, { additionalArgs: ['a.test.ts'] });
@ -251,19 +251,19 @@ test('should match case insensitive', async ({ runInlineTest }) => {
test('should match by directory', async ({ runInlineTest }) => { test('should match by directory', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'dir-a/file.test.ts': ` 'dir-a/file.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
`, `,
'dir-b/file1.test.ts': ` 'dir-b/file1.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
`, `,
'dir-b/file2.test.ts': ` 'dir-b/file2.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
`, `,
'file.test.ts': ` 'file.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
` `
}, {}, {}, { additionalArgs: ['dir-b'] }); }, {}, {}, { additionalArgs: ['dir-b'] });
@ -278,19 +278,19 @@ test('should ignore node_modules even with custom testIgnore', async ({ runInlin
module.exports = { testIgnore: 'a.test.ts' }; module.exports = { testIgnore: 'a.test.ts' };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
`, `,
'node_modules/a.test.ts': ` 'node_modules/a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
`, `,
'node_modules/b.test.ts': ` 'node_modules/b.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
`, `,
'folder/c.test.ts': ` 'folder/c.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
` `
}); });
@ -304,11 +304,11 @@ test('should only match files with JS/TS file extensions', async ({ runInlineTes
module.exports = { testMatch: /foobar/ }; module.exports = { testMatch: /foobar/ };
`, `,
'foobar.test.ts': ` 'foobar.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
`, `,
'foobar.test.js': ` 'foobar.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
`, `,
'foobar.test.ts-snapshots/compares-page-screenshot-chromium-linux-test-chromium.png': ` 'foobar.test.ts-snapshots/compares-page-screenshot-chromium-linux-test-chromium.png': `
@ -322,7 +322,7 @@ test('should only match files with JS/TS file extensions', async ({ runInlineTes
test('should match dot-files', async ({ runInlineTest }) => { test('should match dot-files', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'.a.test.ts': ` '.a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
`, `,
}); });
@ -334,11 +334,11 @@ test('should match dot-files', async ({ runInlineTest }) => {
test('should match in dot-directories', async ({ runInlineTest }) => { test('should match in dot-directories', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'.dir/a.test.ts': ` '.dir/a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
`, `,
'.dir/b.test.js': ` '.dir/b.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
`, `,
}); });
@ -355,15 +355,15 @@ test('should always work with unix separators', async ({ runInlineTest }) => {
module.exports = { testDir: path.join(__dirname, 'dir') }; module.exports = { testDir: path.join(__dirname, 'dir') };
`, `,
'dir/a.test.ts': ` 'dir/a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
`, `,
'dir/b.test.ts': ` 'dir/b.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', ({}) => {}); test('pass', ({}) => {});
` `
}, {}, {}, { additionalArgs: [`dir/a`] }); }, {}, {}, { additionalArgs: [`dir/a`] });

View File

@ -19,7 +19,7 @@ import { test, expect } from './playwright-test-fixtures';
test('should work directly', async ({ runInlineTest }) => { test('should work directly', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test 1', async ({}, testInfo) => { test('test 1', async ({}, testInfo) => {
expect(testInfo.title).toBe('test 1'); expect(testInfo.title).toBe('test 1');
}); });
@ -34,14 +34,16 @@ test('should work directly', async ({ runInlineTest }) => {
test('should work via fixture', async ({ runInlineTest }) => { test('should work via fixture', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'helper.ts': ` 'helper.ts': `
export const test = pwt.test.extend({ import { test as base } from '@playwright/test';
export * from '@playwright/test';
export const test = base.extend({
title: async ({}, run, testInfo) => { title: async ({}, run, testInfo) => {
await run(testInfo.title); await run(testInfo.title);
}, },
}); });
`, `,
'a.test.js': ` 'a.test.js': `
const { test } = require('./helper'); const { test, expect } = require('./helper');
test('test 1', async ({title}) => { test('test 1', async ({title}) => {
expect(title).toBe('test 1'); expect(title).toBe('test 1');
}); });
@ -56,14 +58,16 @@ test('should work via fixture', async ({ runInlineTest }) => {
test('should work via test.info', async ({ runInlineTest }) => { test('should work via test.info', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'helper.ts': ` 'helper.ts': `
export const test = pwt.test.extend({ import { test as base } from '@playwright/test';
export * from '@playwright/test';
export const test = base.extend({
title: async ({}, run) => { title: async ({}, run) => {
await run(pwt.test.info().title); await run(base.info().title);
}, },
}); });
`, `,
'a.test.js': ` 'a.test.js': `
const { test } = require('./helper'); const { test, expect } = require('./helper');
test('test 1', async ({title}) => { test('test 1', async ({title}) => {
expect(test.info().title).toBe('test 1'); expect(test.info().title).toBe('test 1');
expect(title).toBe('test 1'); expect(title).toBe('test 1');
@ -79,7 +83,7 @@ test('should work via test.info', async ({ runInlineTest }) => {
test('should throw outside test', async ({ runInlineTest }) => { test('should throw outside test', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.info(); test.info();
test('test 1', async ({title}) => {}); test('test 1', async ({title}) => {});
`, `,

View File

@ -19,7 +19,8 @@ import { test, expect, expectTestHelper } from './playwright-test-fixtures';
test('test modifiers should work', async ({ runInlineTest }) => { test('test modifiers should work', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'helper.ts': ` 'helper.ts': `
export const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
export const test = base.extend({
foo: true, foo: true,
}); });
`, `,
@ -134,7 +135,7 @@ test.describe('test modifier annotations', () => {
test('should work', async ({ runInlineTest }) => { test('should work', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.describe('suite1', () => { test.describe('suite1', () => {
test('no marker', () => {}); test('no marker', () => {});
@ -163,7 +164,7 @@ test.describe('test modifier annotations', () => {
test('should work alongside top-level modifier', async ({ runInlineTest }) => { test('should work alongside top-level modifier', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.fixme(); test.fixme();
@ -194,7 +195,7 @@ test.describe('test modifier annotations', () => {
test('should work alongside top-level modifier wrapper-style', async ({ runInlineTest }) => { test('should work alongside top-level modifier wrapper-style', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.describe.skip('suite1', () => { test.describe.skip('suite1', () => {
test('no marker', () => {}); test('no marker', () => {});
@ -223,7 +224,7 @@ test.describe('test modifier annotations', () => {
test('should work with nesting', async ({ runInlineTest }) => { test('should work with nesting', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.fixme(); test.fixme();
@ -253,7 +254,7 @@ test.describe('test modifier annotations', () => {
test('should work with only', async ({ runInlineTest }) => { test('should work with only', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.describe.only("suite", () => { test.describe.only("suite", () => {
test.skip('focused skip by suite', () => {}); test.skip('focused skip by suite', () => {});
@ -277,7 +278,7 @@ test.describe('test modifier annotations', () => {
test('should not multiple on retry', async ({ runInlineTest }) => { test('should not multiple on retry', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('retry', () => { test('retry', () => {
test.info().annotations.push({ type: 'example' }); test.info().annotations.push({ type: 'example' });
expect(1).toBe(2); expect(1).toBe(2);
@ -294,7 +295,7 @@ test.describe('test modifier annotations', () => {
test('should not multiply on repeat-each', async ({ runInlineTest }) => { test('should not multiply on repeat-each', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('retry', () => { test('retry', () => {
test.info().annotations.push({ type: 'example' }); test.info().annotations.push({ type: 'example' });
}); });
@ -311,7 +312,8 @@ test.describe('test modifier annotations', () => {
test('test modifiers should check types', async ({ runTSC }) => { test('test modifiers should check types', async ({ runTSC }) => {
const result = await runTSC({ const result = await runTSC({
'helper.ts': ` 'helper.ts': `
export const test = pwt.test.extend<{ foo: boolean }>({ import { test as base, expect } from '@playwright/test';
export const test = base.extend<{ foo: boolean }>({
foo: async ({}, use, testInfo) => { foo: async ({}, use, testInfo) => {
testInfo.skip(); testInfo.skip();
testInfo.fixme(false); testInfo.fixme(false);
@ -377,7 +379,8 @@ test('test modifiers should check types', async ({ runTSC }) => {
test('should skip inside fixture', async ({ runInlineTest }) => { test('should skip inside fixture', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
foo: async ({}, run, testInfo) => { foo: async ({}, run, testInfo) => {
testInfo.skip(true, 'reason'); testInfo.skip(true, 'reason');
await run(); await run();
@ -396,8 +399,9 @@ test('should skip inside fixture', async ({ runInlineTest }) => {
test('modifier with a function should throw in the test', async ({ runInlineTest }) => { test('modifier with a function should throw in the test', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
pwt.test('skipped', async ({}) => { import { test, expect } from '@playwright/test';
pwt.test.skip(() => true); test('skipped', async ({}) => {
test.skip(() => true);
}); });
`, `,
}); });
@ -408,7 +412,8 @@ test('modifier with a function should throw in the test', async ({ runInlineTest
test('test.skip with worker fixtures only should skip before hooks and tests', async ({ runInlineTest }) => { test('test.skip with worker fixtures only should skip before hooks and tests', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
foo: [ 'foo', { scope: 'worker' }], foo: [ 'foo', { scope: 'worker' }],
}); });
const logs = []; const logs = [];
@ -453,7 +458,7 @@ test('test.skip with worker fixtures only should skip before hooks and tests', a
test('test.skip without a callback in describe block should skip hooks', async ({ runInlineTest }) => { test('test.skip without a callback in describe block should skip hooks', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
const logs = []; const logs = [];
test.beforeAll(() => { test.beforeAll(() => {
console.log('%%beforeAll'); console.log('%%beforeAll');
@ -482,7 +487,7 @@ test('test.skip without a callback in describe block should skip hooks', async (
test('test.skip should not define a skipped test inside another test', async ({ runInlineTest }) => { test('test.skip should not define a skipped test inside another test', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
const logs = []; const logs = [];
test('passes', () => { test('passes', () => {
test.skip('foo', () => { test.skip('foo', () => {
@ -500,7 +505,7 @@ test('test.skip should not define a skipped test inside another test', async ({
test('modifier timeout should be reported', async ({ runInlineTest }) => { test('modifier timeout should be reported', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.skip(async () => new Promise(() => {})); test.skip(async () => new Promise(() => {}));
test('fails', () => { test('fails', () => {
}); });
@ -509,13 +514,13 @@ test('modifier timeout should be reported', async ({ runInlineTest }) => {
expect(result.exitCode).toBe(1); expect(result.exitCode).toBe(1);
expect(result.failed).toBe(1); expect(result.failed).toBe(1);
expect(result.output).toContain('"skip" modifier timeout of 2000ms exceeded.'); expect(result.output).toContain('"skip" modifier timeout of 2000ms exceeded.');
expect(result.output).toContain('6 | test.skip(async () => new Promise(() => {}));'); expect(result.output).toContain('3 | test.skip(async () => new Promise(() => {}));');
}); });
test('should not run hooks if modifier throws', async ({ runInlineTest }) => { test('should not run hooks if modifier throws', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.skip(() => { test.skip(() => {
console.log('%%modifier'); console.log('%%modifier');
throw new Error('Oh my'); throw new Error('Oh my');
@ -564,7 +569,7 @@ test('should report skipped tests in-order with correct properties', async ({ ru
module.exports = { reporter: [['./reporter.ts']] }; module.exports = { reporter: [['./reporter.ts']] };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.describe.configure({ timeout: 1234, retries: 3 }); test.describe.configure({ timeout: 1234, retries: 3 });
test('test1', async ({}) => { test('test1', async ({}) => {
}); });

View File

@ -28,7 +28,7 @@ test('should work and remove non-failures', async ({ runInlineTest }, testInfo)
}; };
`, `,
'dir/my-test.spec.js': ` 'dir/my-test.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test 1', async ({}, testInfo) => { test('test 1', async ({}, testInfo) => {
if (testInfo.retry) { if (testInfo.retry) {
expect(testInfo.outputDir).toContain('my-test-test-1-chromium-retry' + testInfo.retry); expect(testInfo.outputDir).toContain('my-test-test-1-chromium-retry' + testInfo.retry);
@ -70,7 +70,7 @@ test('should work and remove non-failures', async ({ runInlineTest }, testInfo)
test('should include repeat token', async ({ runInlineTest }) => { test('should include repeat token', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.js': ` 'a.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test', ({}, testInfo) => { test('test', ({}, testInfo) => {
if (testInfo.repeatEachIndex) if (testInfo.repeatEachIndex)
expect(testInfo.outputPath('')).toContain('repeat' + testInfo.repeatEachIndex); expect(testInfo.outputPath('')).toContain('repeat' + testInfo.repeatEachIndex);
@ -90,7 +90,7 @@ test('should default to package.json directory', async ({ runInlineTest }, testI
module.exports = { projects: [ {} ] }; module.exports = { projects: [ {} ] };
`, `,
'foo/bar/baz/tests/a.spec.js': ` 'foo/bar/baz/tests/a.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
const fs = require('fs'); const fs = require('fs');
test('pass', ({}, testInfo) => { test('pass', ({}, testInfo) => {
expect(process.cwd()).toBe(__dirname); expect(process.cwd()).toBe(__dirname);
@ -112,7 +112,7 @@ test('should default to package.json directory', async ({ runInlineTest }, testI
test('should be unique for beforeAll hook from different workers', async ({ runInlineTest }, testInfo) => { test('should be unique for beforeAll hook from different workers', async ({ runInlineTest }, testInfo) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.js': ` 'a.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.beforeAll(({}, testInfo) => { test.beforeAll(({}, testInfo) => {
console.log('\\n%%' + testInfo.outputDir); console.log('\\n%%' + testInfo.outputDir);
}); });
@ -136,13 +136,14 @@ test('should be unique for beforeAll hook from different workers', async ({ runI
test('should include the project name', async ({ runInlineTest }) => { test('should include the project name', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'helper.ts': ` 'helper.ts': `
export const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
export const test = base.extend({
auto: [ async ({}, run, testInfo) => { auto: [ async ({}, run, testInfo) => {
testInfo.snapshotSuffix = ''; testInfo.snapshotSuffix = '';
await run(); await run();
}, { auto: true } ] }, { auto: true } ]
}); });
export const test2 = pwt.test.extend({ export const test2 = base.extend({
auto: [ async ({}, run, testInfo) => { auto: [ async ({}, run, testInfo) => {
testInfo.snapshotSuffix = 'suffix'; testInfo.snapshotSuffix = 'suffix';
await run(); await run();
@ -219,7 +220,8 @@ test('should include the project name', async ({ runInlineTest }) => {
test('should include path option in snapshot', async ({ runInlineTest }) => { test('should include path option in snapshot', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'helper.ts': ` 'helper.ts': `
export const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
export const test = base.extend({
auto: [ async ({}, run, testInfo) => { auto: [ async ({}, run, testInfo) => {
testInfo.snapshotSuffix = 'suffix'; testInfo.snapshotSuffix = 'suffix';
await run(); await run();
@ -247,7 +249,8 @@ test('should include path option in snapshot', async ({ runInlineTest }) => {
test('should error if outputPath is resolved to outside of parent', async ({ runInlineTest }) => { test('should error if outputPath is resolved to outside of parent', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'helper.ts': ` 'helper.ts': `
export const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
export const test = base.extend({
auto: [ async ({}, run, testInfo) => { auto: [ async ({}, run, testInfo) => {
testInfo.snapshotSuffix = 'suffix'; testInfo.snapshotSuffix = 'suffix';
await run(); await run();
@ -295,7 +298,7 @@ test('should remove output dirs for projects run', async ({ runInlineTest }, tes
] }; ] };
`, `,
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('my test', ({}, testInfo) => {}); test('my test', ({}, testInfo) => {});
` `
}, { output: '' }); }, { output: '' });
@ -313,7 +316,7 @@ test('should remove folders with preserveOutput=never', async ({ runInlineTest }
export default { preserveOutput: 'never' }; export default { preserveOutput: 'never' };
`, `,
'dir/my-test.spec.js': ` 'dir/my-test.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test 1', async ({}, testInfo) => { test('test 1', async ({}, testInfo) => {
require('fs').writeFileSync(testInfo.outputPath('file.txt'), 'content', 'utf-8'); require('fs').writeFileSync(testInfo.outputPath('file.txt'), 'content', 'utf-8');
if (testInfo.retry < 2) if (testInfo.retry < 2)
@ -332,7 +335,7 @@ test('should remove folders with preserveOutput=never', async ({ runInlineTest }
test('should preserve failed results', async ({ runInlineTest }, testInfo) => { test('should preserve failed results', async ({ runInlineTest }, testInfo) => {
const result = await runInlineTest({ const result = await runInlineTest({
'dir/my-test.spec.js': ` 'dir/my-test.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test 1', async ({}, testInfo) => { test('test 1', async ({}, testInfo) => {
require('fs').writeFileSync(testInfo.outputPath('file.txt'), 'content', 'utf-8'); require('fs').writeFileSync(testInfo.outputPath('file.txt'), 'content', 'utf-8');
if (testInfo.retry < 2) if (testInfo.retry < 2)
@ -351,7 +354,7 @@ test('should preserve failed results', async ({ runInlineTest }, testInfo) => {
test('should accept a relative path for outputDir', async ({ runInlineTest }, testInfo) => { test('should accept a relative path for outputDir', async ({ runInlineTest }, testInfo) => {
const result = await runInlineTest({ const result = await runInlineTest({
'my-test.spec.js': ` 'my-test.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test', async ({}, testInfo) => { test('test', async ({}, testInfo) => {
expect(testInfo.outputDir).toBe(${JSON.stringify(path.join(testInfo.outputDir, './my-output-dir', 'my-test-test'))}); expect(testInfo.outputDir).toBe(${JSON.stringify(path.join(testInfo.outputDir, './my-output-dir', 'my-test-test'))});
}); });
@ -374,7 +377,7 @@ test('should have output dir based on rootDir (cwd)', async ({ runInlineTest },
outputDir: 'test-results/', outputDir: 'test-results/',
};`, };`,
'e2e/example.spec.js': ` 'e2e/example.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
const fs = require('fs'); const fs = require('fs');
test('hello world', async ({ }, testInfo) => { test('hello world', async ({ }, testInfo) => {
fs.writeFileSync(testInfo.outputPath('foo.txt'), 'hello'); fs.writeFileSync(testInfo.outputPath('foo.txt'), 'hello');
@ -389,7 +392,7 @@ test('should have output dir based on rootDir (cwd)', async ({ runInlineTest },
test('should allow nonAscii characters in the output dir', async ({ runInlineTest }, testInfo) => { test('should allow nonAscii characters in the output dir', async ({ runInlineTest }, testInfo) => {
const result = await runInlineTest({ const result = await runInlineTest({
'my-test.spec.js': ` 'my-test.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('こんにちは世界', async ({}, testInfo) => { test('こんにちは世界', async ({}, testInfo) => {
console.log('\\n%%' + testInfo.outputDir); console.log('\\n%%' + testInfo.outputDir);
}); });
@ -402,7 +405,7 @@ test('should allow nonAscii characters in the output dir', async ({ runInlineTes
test('should allow shorten long output dirs characters in the output dir', async ({ runInlineTest }, testInfo) => { test('should allow shorten long output dirs characters in the output dir', async ({ runInlineTest }, testInfo) => {
const result = await runInlineTest({ const result = await runInlineTest({
'very/deep/and/long/file/name/that/i/want/to/be/trimmed/my-test.spec.js': ` 'very/deep/and/long/file/name/that/i/want/to/be/trimmed/my-test.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.describe('this is a really long description that would be too long for a file path', () => { test.describe('this is a really long description that would be too long for a file path', () => {
test('and this is an even longer test name that just keeps going and going and we should shorten it', async ({}, testInfo) => { test('and this is an even longer test name that just keeps going and going and we should shorten it', async ({}, testInfo) => {
console.log('\\n%%' + testInfo.outputDir); console.log('\\n%%' + testInfo.outputDir);
@ -417,7 +420,7 @@ test('should allow shorten long output dirs characters in the output dir', async
test('should not mangle double dashes', async ({ runInlineTest }, testInfo) => { test('should not mangle double dashes', async ({ runInlineTest }, testInfo) => {
const result = await runInlineTest({ const result = await runInlineTest({
'my--file.spec.js': ` 'my--file.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('my--test', async ({}, testInfo) => { test('my--test', async ({}, testInfo) => {
console.log('\\n%%' + testInfo.outputDir); console.log('\\n%%' + testInfo.outputDir);
}); });
@ -430,7 +433,7 @@ test('should not mangle double dashes', async ({ runInlineTest }, testInfo) => {
test('should allow include the describe name the output dir', async ({ runInlineTest }, testInfo) => { test('should allow include the describe name the output dir', async ({ runInlineTest }, testInfo) => {
const result = await runInlineTest({ const result = await runInlineTest({
'my-test.spec.js': ` 'my-test.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.describe('hello', () => { test.describe('hello', () => {
test('world', async ({}, testInfo) => { test('world', async ({}, testInfo) => {
console.log('\\n%%' + testInfo.outputDir); console.log('\\n%%' + testInfo.outputDir);

View File

@ -19,7 +19,7 @@ import { test, expect, countTimes } from './playwright-test-fixtures';
test('test.describe.parallel should throw inside test.describe.serial', async ({ runInlineTest }) => { test('test.describe.parallel should throw inside test.describe.serial', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.describe.serial('serial suite', () => { test.describe.serial('serial suite', () => {
test.describe.parallel('parallel suite', () => { test.describe.parallel('parallel suite', () => {
}); });
@ -28,13 +28,13 @@ test('test.describe.parallel should throw inside test.describe.serial', async ({
}); });
expect(result.exitCode).toBe(1); expect(result.exitCode).toBe(1);
expect(result.output).toContain('Error: describe.parallel cannot be nested inside describe.serial'); expect(result.output).toContain('Error: describe.parallel cannot be nested inside describe.serial');
expect(result.output).toContain('a.test.ts:7'); expect(result.output).toContain('a.test.ts:4');
}); });
test('test.describe.parallel should work', async ({ runInlineTest }) => { test('test.describe.parallel should work', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.describe.parallel('parallel suite', () => { test.describe.parallel('parallel suite', () => {
test('test1', async ({}, testInfo) => { test('test1', async ({}, testInfo) => {
console.log('\\n%% worker=' + testInfo.workerIndex); console.log('\\n%% worker=' + testInfo.workerIndex);
@ -63,7 +63,7 @@ test('test.describe.parallel should work', async ({ runInlineTest }) => {
test('test.describe.parallel should work in file', async ({ runInlineTest }) => { test('test.describe.parallel should work in file', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.describe.configure({ mode: 'parallel' }); test.describe.configure({ mode: 'parallel' });
test('test1', async ({}, testInfo) => { test('test1', async ({}, testInfo) => {
console.log('\\n%% worker=' + testInfo.workerIndex); console.log('\\n%% worker=' + testInfo.workerIndex);
@ -91,7 +91,7 @@ test('test.describe.parallel should work in file', async ({ runInlineTest }) =>
test('test.describe.parallel should work in describe', async ({ runInlineTest }) => { test('test.describe.parallel should work in describe', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.describe('parallel suite', () => { test.describe('parallel suite', () => {
test.describe.configure({ mode: 'parallel' }); test.describe.configure({ mode: 'parallel' });
test('test1', async ({}, testInfo) => { test('test1', async ({}, testInfo) => {
@ -124,7 +124,7 @@ test('config.fullyParallel should work', async ({ runInlineTest }) => {
module.exports = { fullyParallel: true }; module.exports = { fullyParallel: true };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test1', async ({}, testInfo) => { test('test1', async ({}, testInfo) => {
console.log('\\n%% worker=' + testInfo.workerIndex); console.log('\\n%% worker=' + testInfo.workerIndex);
await new Promise(f => setTimeout(f, 1000)); await new Promise(f => setTimeout(f, 1000));
@ -154,7 +154,7 @@ test('project.fullyParallel should work', async ({ runInlineTest }) => {
module.exports = { projects: [ { fullyParallel: true } ] }; module.exports = { projects: [ { fullyParallel: true } ] };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test1', async ({}, testInfo) => { test('test1', async ({}, testInfo) => {
console.log('\\n%% worker=' + testInfo.workerIndex); console.log('\\n%% worker=' + testInfo.workerIndex);
await new Promise(f => setTimeout(f, 1000)); await new Promise(f => setTimeout(f, 1000));
@ -181,7 +181,7 @@ test('project.fullyParallel should work', async ({ runInlineTest }) => {
test('parallel mode should minimize running beforeAll/afterAll hooks', async ({ runInlineTest }) => { test('parallel mode should minimize running beforeAll/afterAll hooks', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.describe.configure({ mode: 'parallel' }); test.describe.configure({ mode: 'parallel' });
test.beforeAll(() => { test.beforeAll(() => {
console.log('\\n%%beforeAll'); console.log('\\n%%beforeAll');
@ -204,7 +204,7 @@ test('parallel mode should minimize running beforeAll/afterAll hooks', async ({
test('parallel mode should minimize running beforeAll/afterAll hooks 2', async ({ runInlineTest }) => { test('parallel mode should minimize running beforeAll/afterAll hooks 2', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.describe.configure({ mode: 'parallel' }); test.describe.configure({ mode: 'parallel' });
test.beforeAll(() => { test.beforeAll(() => {
console.log('\\n%%beforeAll'); console.log('\\n%%beforeAll');

View File

@ -19,7 +19,7 @@ import { test, expect } from './playwright-test-fixtures';
test('test.describe.serial should work', async ({ runInlineTest }) => { test('test.describe.serial should work', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.describe.serial('serial suite', () => { test.describe.serial('serial suite', () => {
test('test1', async ({}) => { test('test1', async ({}) => {
console.log('\\n%%test1'); console.log('\\n%%test1');
@ -58,7 +58,7 @@ test('test.describe.serial should work', async ({ runInlineTest }) => {
test('test.describe.serial should work in describe', async ({ runInlineTest }) => { test('test.describe.serial should work in describe', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.describe('serial suite', () => { test.describe('serial suite', () => {
test.describe.configure({ mode: 'serial' }); test.describe.configure({ mode: 'serial' });
test('test1', async ({}) => { test('test1', async ({}) => {
@ -98,7 +98,7 @@ test('test.describe.serial should work in describe', async ({ runInlineTest }) =
test('test.describe.serial should work with retry', async ({ runInlineTest }) => { test('test.describe.serial should work with retry', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.describe.serial('serial suite', () => { test.describe.serial('serial suite', () => {
test('test1', async ({}) => { test('test1', async ({}) => {
console.log('\\n%%test1'); console.log('\\n%%test1');
@ -143,7 +143,7 @@ test('test.describe.serial should work with retry', async ({ runInlineTest }) =>
test('test.describe.serial should work with retry and beforeAll failure', async ({ runInlineTest }) => { test('test.describe.serial should work with retry and beforeAll failure', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.describe.serial('serial suite', () => { test.describe.serial('serial suite', () => {
test('test1', async ({}) => { test('test1', async ({}) => {
console.log('\\n%%test1'); console.log('\\n%%test1');
@ -178,7 +178,7 @@ test('test.describe.serial should work with retry and beforeAll failure', async
test('test.describe.serial should work with retry and afterAll failure', async ({ runInlineTest }) => { test('test.describe.serial should work with retry and afterAll failure', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.describe.serial('serial suite', () => { test.describe.serial('serial suite', () => {
test.describe('inner suite', () => { test.describe('inner suite', () => {
let firstRun = false; let firstRun = false;
@ -215,7 +215,7 @@ test('test.describe.serial should work with retry and afterAll failure', async (
test('test.describe.serial.only should work', async ({ runInlineTest }) => { test('test.describe.serial.only should work', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('test1', async ({}) => { test('test1', async ({}) => {
console.log('\\n%%test1'); console.log('\\n%%test1');
}); });
@ -245,7 +245,7 @@ test('test.describe.serial.only should work', async ({ runInlineTest }) => {
test('test.describe.serial should work with test.fail', async ({ runInlineTest }) => { test('test.describe.serial should work with test.fail', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.describe.serial('suite', () => { test.describe.serial('suite', () => {
test('zero', () => { test('zero', () => {
console.log('\\n%%zero'); console.log('\\n%%zero');
@ -283,7 +283,7 @@ test('test.describe.serial should work with test.fail', async ({ runInlineTest }
test('test.describe.serial should work with test.fail and retries', async ({ runInlineTest }) => { test('test.describe.serial should work with test.fail and retries', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.describe.serial('suite', () => { test.describe.serial('suite', () => {
test('zero', () => { test('zero', () => {
console.log('\\n%%zero'); console.log('\\n%%zero');
@ -326,7 +326,7 @@ test('test.describe.serial should work with test.fail and retries', async ({ run
test('test.describe.serial should work inside test.describe.parallel', async ({ runInlineTest }) => { test('test.describe.serial should work inside test.describe.parallel', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.describe.parallel('parallel suite', () => { test.describe.parallel('parallel suite', () => {
test.describe.serial('serial suite', () => { test.describe.serial('serial suite', () => {
test('one', async ({}) => { test('one', async ({}) => {
@ -374,7 +374,7 @@ test('test.describe.serial should work with fullyParallel', async ({ runInlineTe
module.exports = { fullyParallel: true }; module.exports = { fullyParallel: true };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.describe.serial('serial suite', () => { test.describe.serial('serial suite', () => {
test('one', async ({}) => { test('one', async ({}) => {
await new Promise(f => setTimeout(f, 1000)); await new Promise(f => setTimeout(f, 1000));

View File

@ -66,7 +66,7 @@ test('should report api step hierarchy', async ({ runInlineTest }) => {
}; };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async ({ page }) => { test('pass', async ({ page }) => {
await test.step('outer step 1', async () => { await test.step('outer step 1', async () => {
await test.step('inner step 1.1', async () => {}); await test.step('inner step 1.1', async () => {});
@ -173,7 +173,7 @@ test('should not report nested after hooks', async ({ runInlineTest }) => {
}; };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('timeout', async ({ page }) => { test('timeout', async ({ page }) => {
await test.step('my step', async () => { await test.step('my step', async () => {
await new Promise(() => {}); await new Promise(() => {});
@ -238,9 +238,10 @@ test('should report test.step from fixtures', async ({ runInlineTest }) => {
}; };
`, `,
'a.test.ts': ` 'a.test.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
foo: async ({}, use) => { foo: async ({}, use) => {
await pwt.test.step('setup foo', () => {}); await base.step('setup foo', () => {});
await use(async () => { await use(async () => {
await test.step('inside foo', () => {}); await test.step('inside foo', () => {});
}); });
@ -281,7 +282,7 @@ test('should report expect step locations', async ({ runInlineTest }) => {
}; };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async ({ page }) => { test('pass', async ({ page }) => {
expect(true).toBeTruthy(); expect(true).toBeTruthy();
}); });
@ -351,7 +352,7 @@ test('should report custom expect steps', async ({ runInlineTest }) => {
}, },
}); });
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async ({}) => { test('pass', async ({}) => {
expect(15).toBeWithinRange(10, 20); expect(15).toBeWithinRange(10, 20);
}); });
@ -384,7 +385,7 @@ test('should report custom expect steps', async ({ runInlineTest }) => {
test('should return value from step', async ({ runInlineTest }) => { test('should return value from step', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('steps with return values', async ({ page }) => { test('steps with return values', async ({ page }) => {
const v1 = await test.step('my step', () => { const v1 = await test.step('my step', () => {
return 10; return 10;
@ -412,7 +413,7 @@ test('should mark step as failed when soft expect fails', async ({ runInlineTest
}; };
`, `,
'a.test.ts': ` 'a.test.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async ({}) => { test('pass', async ({}) => {
await test.step('outer', async () => { await test.step('outer', async () => {
await test.step('inner', async () => { await test.step('inner', async () => {

View File

@ -19,7 +19,8 @@ import { test, expect } from './playwright-test-fixtures';
test('should merge options', async ({ runInlineTest }) => { test('should merge options', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
foo: 'foo', foo: 'foo',
bar: 'bar', bar: 'bar',
}); });
@ -39,12 +40,14 @@ test('should merge options', async ({ runInlineTest }) => {
test('should run tests with different test options in the same worker', async ({ runInlineTest }) => { test('should run tests with different test options in the same worker', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'helper.ts': ` 'helper.ts': `
export const test = pwt.test.extend({ import { test as base } from '@playwright/test';
export * from '@playwright/test';
export const test = base.extend({
foo: 'foo', foo: 'foo',
}); });
`, `,
'a.test.ts': ` 'a.test.ts': `
import { test } from './helper'; import { test, expect } from './helper';
test('test', ({ foo }, testInfo) => { test('test', ({ foo }, testInfo) => {
expect(foo).toBe('foo'); expect(foo).toBe('foo');
expect(testInfo.workerIndex).toBe(0); expect(testInfo.workerIndex).toBe(0);
@ -74,7 +77,8 @@ test('should run tests with different test options in the same worker', async ({
test('should throw when setting worker options in describe', async ({ runInlineTest }) => { test('should throw when setting worker options in describe', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
foo: [undefined, { scope: 'worker' }], foo: [undefined, { scope: 'worker' }],
}); });
test.describe('suite', () => { test.describe('suite', () => {
@ -96,19 +100,21 @@ test('should throw when setting worker options in describe', async ({ runInlineT
test('should run tests with different worker options', async ({ runInlineTest }) => { test('should run tests with different worker options', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'helper.ts': ` 'helper.ts': `
export const test = pwt.test.extend({ import { test as base } from '@playwright/test';
export * from '@playwright/test';
export const test = base.extend({
foo: [undefined, { scope: 'worker' }], foo: [undefined, { scope: 'worker' }],
}); });
`, `,
'a.test.ts': ` 'a.test.ts': `
import { test } from './helper'; import { test, expect } from './helper';
test('test', ({ foo }, testInfo) => { test('test', ({ foo }, testInfo) => {
expect(foo).toBe(undefined); expect(foo).toBe(undefined);
expect(testInfo.workerIndex).toBe(0); expect(testInfo.workerIndex).toBe(0);
}); });
`, `,
'b.test.ts': ` 'b.test.ts': `
import { test } from './helper'; import { test, expect } from './helper';
test.use({ foo: 'bar' }); test.use({ foo: 'bar' });
test('test1', ({ foo }, testInfo) => { test('test1', ({ foo }, testInfo) => {
@ -122,7 +128,7 @@ test('should run tests with different worker options', async ({ runInlineTest })
}); });
`, `,
'c.test.ts': ` 'c.test.ts': `
import { test } from './helper'; import { test, expect } from './helper';
test.use({ foo: 'baz' }); test.use({ foo: 'baz' });
test('test2', ({ foo }, testInfo) => { test('test2', ({ foo }, testInfo) => {
expect(foo).toBe('baz'); expect(foo).toBe('baz');
@ -138,7 +144,9 @@ test('should run tests with different worker options', async ({ runInlineTest })
test('should use options from the config', async ({ runInlineTest }) => { test('should use options from the config', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'helper.ts': ` 'helper.ts': `
export const test = pwt.test.extend({ import { test as base } from '@playwright/test';
export * from '@playwright/test';
export const test = base.extend({
foo: [ 'foo', { option: true } ], foo: [ 'foo', { option: true } ],
}); });
`, `,
@ -146,7 +154,7 @@ test('should use options from the config', async ({ runInlineTest }) => {
module.exports = { use: { foo: 'bar' } }; module.exports = { use: { foo: 'bar' } };
`, `,
'a.test.ts': ` 'a.test.ts': `
import { test } from './helper'; import { test, expect } from './helper';
test('test1', ({ foo }) => { test('test1', ({ foo }) => {
expect(foo).toBe('bar'); expect(foo).toBe('bar');
}); });
@ -167,7 +175,7 @@ test('should use options from the config', async ({ runInlineTest }) => {
test('test.use() should throw if called from beforeAll ', async ({ runInlineTest }) => { test('test.use() should throw if called from beforeAll ', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.ts': ` 'a.test.ts': `
const test = pwt.test; import { test, expect } from '@playwright/test';
test.beforeAll(() => { test.beforeAll(() => {
test.use({}); test.use({});
}); });

View File

@ -19,7 +19,8 @@ import { test, expect } from './playwright-test-fixtures';
test('should run fixture teardown on timeout', async ({ runInlineTest }) => { test('should run fixture teardown on timeout', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'helper.ts': ` 'helper.ts': `
export const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
export const test = base.extend({
foo: async ({}, run, testInfo) => { foo: async ({}, run, testInfo) => {
await run(); await run();
console.log('STATUS:' + testInfo.status); console.log('STATUS:' + testInfo.status);
@ -41,7 +42,7 @@ test('should run fixture teardown on timeout', async ({ runInlineTest }) => {
test('should respect test.setTimeout', async ({ runInlineTest }) => { test('should respect test.setTimeout', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('fails', async ({}) => { test('fails', async ({}) => {
await new Promise(f => setTimeout(f, 1500)); await new Promise(f => setTimeout(f, 1500));
}); });
@ -71,7 +72,7 @@ test('should respect test.setTimeout', async ({ runInlineTest }) => {
test('should respect test.setTimeout outside of the test', async ({ runInlineTest }) => { test('should respect test.setTimeout outside of the test', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.setTimeout(1000); test.setTimeout(1000);
test('fails', async ({}) => { test('fails', async ({}) => {
@ -101,7 +102,7 @@ test('should respect test.setTimeout outside of the test', async ({ runInlineTes
test('should timeout when calling test.setTimeout too late', async ({ runInlineTest }) => { test('should timeout when calling test.setTimeout too late', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('fails', async ({}) => { test('fails', async ({}) => {
await new Promise(f => setTimeout(f, 500)); await new Promise(f => setTimeout(f, 500));
test.setTimeout(100); test.setTimeout(100);
@ -118,7 +119,7 @@ test('should timeout when calling test.setTimeout too late', async ({ runInlineT
test('should respect test.slow', async ({ runInlineTest }) => { test('should respect test.slow', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('fails', async ({}) => { test('fails', async ({}) => {
await new Promise(f => setTimeout(f, 1500)); await new Promise(f => setTimeout(f, 1500));
}); });
@ -145,7 +146,8 @@ test('should respect test.slow', async ({ runInlineTest }) => {
test('should ignore test.setTimeout when debugging', async ({ runInlineTest }) => { test('should ignore test.setTimeout when debugging', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
fixture: async ({}, use) => { fixture: async ({}, use) => {
test.setTimeout(100); test.setTimeout(100);
await new Promise(f => setTimeout(f, 200)); await new Promise(f => setTimeout(f, 200));
@ -165,7 +167,8 @@ test('should ignore test.setTimeout when debugging', async ({ runInlineTest }) =
test('should respect fixture timeout', async ({ runInlineTest }) => { test('should respect fixture timeout', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
fixture: [async ({}, use) => { fixture: [async ({}, use) => {
await new Promise(f => setTimeout(f, 300)); await new Promise(f => setTimeout(f, 300));
await use('hey'); await use('hey');
@ -199,13 +202,14 @@ test('should respect fixture timeout', async ({ runInlineTest }) => {
expect(result.failed).toBe(2); expect(result.failed).toBe(2);
expect(result.output).toContain('Fixture "custom title" timeout of 500ms exceeded.'); expect(result.output).toContain('Fixture "custom title" timeout of 500ms exceeded.');
expect(result.output).toContain('Fixture "slowTeardown" timeout of 400ms exceeded.'); expect(result.output).toContain('Fixture "slowTeardown" timeout of 400ms exceeded.');
expect(result.output).toContain('> 5 | const test = pwt.test.extend({'); expect(result.output).toContain('> 3 | const test = base.extend({');
}); });
test('should respect test.setTimeout in the worker fixture', async ({ runInlineTest }) => { test('should respect test.setTimeout in the worker fixture', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
fixture: [async ({}, use) => { fixture: [async ({}, use) => {
await new Promise(f => setTimeout(f, 300)); await new Promise(f => setTimeout(f, 300));
await use('hey'); await use('hey');
@ -244,7 +248,8 @@ test('should respect test.setTimeout in the worker fixture', async ({ runInlineT
test('fixture time in beforeAll hook should not affect test', async ({ runInlineTest }) => { test('fixture time in beforeAll hook should not affect test', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
fixture: async ({}, use) => { fixture: async ({}, use) => {
await new Promise(f => setTimeout(f, 500)); await new Promise(f => setTimeout(f, 500));
await use('hey'); await use('hey');
@ -266,7 +271,8 @@ test('fixture time in beforeAll hook should not affect test', async ({ runInline
test('fixture timeout in beforeAll hook should not affect test', async ({ runInlineTest }) => { test('fixture timeout in beforeAll hook should not affect test', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
fixture: [async ({}, use) => { fixture: [async ({}, use) => {
await new Promise(f => setTimeout(f, 500)); await new Promise(f => setTimeout(f, 500));
await use('hey'); await use('hey');
@ -288,7 +294,8 @@ test('fixture timeout in beforeAll hook should not affect test', async ({ runInl
test('fixture time in beforeEach hook should affect test', async ({ runInlineTest }) => { test('fixture time in beforeEach hook should affect test', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
fixture: async ({}, use) => { fixture: async ({}, use) => {
await new Promise(f => setTimeout(f, 500)); await new Promise(f => setTimeout(f, 500));
await use('hey'); await use('hey');
@ -311,7 +318,8 @@ test('fixture time in beforeEach hook should affect test', async ({ runInlineTes
test('test timeout should still run hooks before fixtures teardown', async ({ runInlineTest }) => { test('test timeout should still run hooks before fixtures teardown', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
auto: [async ({}, use) => { auto: [async ({}, use) => {
console.log('\\n%%before-auto'); console.log('\\n%%before-auto');
await use('hey'); await use('hey');
@ -345,7 +353,8 @@ test('test timeout should still run hooks before fixtures teardown', async ({ ru
test('should not include fixtures with own timeout and beforeAll in test duration', async ({ runInlineTest }) => { test('should not include fixtures with own timeout and beforeAll in test duration', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'c.spec.ts': ` 'c.spec.ts': `
const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
const test = base.extend({
foo: [async ({}, use) => { foo: [async ({}, use) => {
await new Promise(f => setTimeout(f, 1000)); await new Promise(f => setTimeout(f, 1000));
await use('foo'); await use('foo');
@ -383,7 +392,8 @@ test('should not include fixtures with own timeout and beforeAll in test duratio
test('should run fixture teardowns after timeout with soft expect error', async ({ runInlineTest }) => { test('should run fixture teardowns after timeout with soft expect error', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'helper.ts': ` 'helper.ts': `
export const test = pwt.test.extend({ import { test as base, expect } from '@playwright/test';
export const test = base.extend({
foo: async ({}, run, testInfo) => { foo: async ({}, run, testInfo) => {
await run(); await run();
await new Promise(f => setTimeout(f, 500)); await new Promise(f => setTimeout(f, 500));
@ -422,7 +432,7 @@ test('should run fixture teardowns after timeout with soft expect error', async
test('should respect test.describe.configure', async ({ runInlineTest }) => { test('should respect test.describe.configure', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.describe.configure({ timeout: 1000 }); test.describe.configure({ timeout: 1000 });
test('test1', async ({}) => { test('test1', async ({}) => {
console.log('test1-' + test.info().timeout); console.log('test1-' + test.info().timeout);

View File

@ -41,7 +41,8 @@ test('should fail to screenshot a page with infinite animation', async ({ runInl
}, },
}), }),
'a.spec.js': ` 'a.spec.js': `
pwt.test('is a test', async ({ page }) => { const { test, expect } = require('@playwright/test');
test('is a test', async ({ page }) => {
await page.goto('${infiniteAnimationURL}'); await page.goto('${infiniteAnimationURL}');
await expect(page).toHaveScreenshot({ timeout: 2000 }); await expect(page).toHaveScreenshot({ timeout: 2000 });
}); });
@ -63,7 +64,8 @@ test('should disable animations by default', async ({ runInlineTest }, testInfo)
const result = await runInlineTest({ const result = await runInlineTest({
...playwrightConfig({}), ...playwrightConfig({}),
'a.spec.js': ` 'a.spec.js': `
pwt.test('is a test', async ({ page }) => { const { test, expect } = require('@playwright/test');
test('is a test', async ({ page }) => {
await page.goto('${cssTransitionURL}'); await page.goto('${cssTransitionURL}');
await expect(page).toHaveScreenshot({ timeout: 2000 }); await expect(page).toHaveScreenshot({ timeout: 2000 });
}); });
@ -80,7 +82,8 @@ test.describe('expect config animations option', () => {
expect: { toHaveScreenshot: { animations: 'disabled' } }, expect: { toHaveScreenshot: { animations: 'disabled' } },
}), }),
'a.spec.js': ` 'a.spec.js': `
pwt.test('is a test', async ({ page }) => { const { test, expect } = require('@playwright/test');
test('is a test', async ({ page }) => {
await page.goto('${cssTransitionURL}'); await page.goto('${cssTransitionURL}');
await expect(page).toHaveScreenshot({ timeout: 2000 }); await expect(page).toHaveScreenshot({ timeout: 2000 });
}); });
@ -96,7 +99,8 @@ test.describe('expect config animations option', () => {
expect: { toHaveScreenshot: { animations: 'allow' } }, expect: { toHaveScreenshot: { animations: 'allow' } },
}), }),
'a.spec.js': ` 'a.spec.js': `
pwt.test('is a test', async ({ page }) => { const { test, expect } = require('@playwright/test');
test('is a test', async ({ page }) => {
await page.goto('${cssTransitionURL}'); await page.goto('${cssTransitionURL}');
await expect(page).toHaveScreenshot({ timeout: 2000 }); await expect(page).toHaveScreenshot({ timeout: 2000 });
}); });
@ -113,7 +117,8 @@ test('should fail with proper error when unsupported argument is given', async (
const result = await runInlineTest({ const result = await runInlineTest({
...playwrightConfig({}), ...playwrightConfig({}),
'a.spec.js': ` 'a.spec.js': `
pwt.test('is a test', async ({ page }) => { const { test, expect } = require('@playwright/test');
test('is a test', async ({ page }) => {
await page.goto('${cssTransitionURL}'); await page.goto('${cssTransitionURL}');
await expect(page).toHaveScreenshot({ await expect(page).toHaveScreenshot({
clip: { clip: {
@ -137,7 +142,8 @@ test('should have scale:css by default', async ({ runInlineTest }, testInfo) =>
snapshotPathTemplate: '__screenshots__/{testFilePath}/{arg}{ext}', snapshotPathTemplate: '__screenshots__/{testFilePath}/{arg}{ext}',
}), }),
'a.spec.js': ` 'a.spec.js': `
pwt.test('is a test', async ({ browser }) => { const { test, expect } = require('@playwright/test');
test('is a test', async ({ browser }) => {
const context = await browser.newContext({ const context = await browser.newContext({
viewport: { width: ${IMG_WIDTH}, height: ${IMG_HEIGHT} }, viewport: { width: ${IMG_WIDTH}, height: ${IMG_HEIGHT} },
deviceScaleFactor: 2, deviceScaleFactor: 2,
@ -165,7 +171,8 @@ test('should ignore non-documented options in toHaveScreenshot config', async ({
}, },
}), }),
'a.spec.js': ` 'a.spec.js': `
pwt.test('is a test', async ({ page }) => { const { test, expect } = require('@playwright/test');
test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot('snapshot.png'); await expect(page).toHaveScreenshot('snapshot.png');
}); });
` `
@ -188,7 +195,8 @@ test('should report toHaveScreenshot step with expectation name in title', async
`, `,
...playwrightConfig({ reporter: './reporter' }), ...playwrightConfig({ reporter: './reporter' }),
'a.spec.js': ` 'a.spec.js': `
pwt.test('is a test', async ({ page }) => { const { test, expect } = require('@playwright/test');
test('is a test', async ({ page }) => {
// Named expectation. // Named expectation.
await expect(page).toHaveScreenshot('foo.png', { timeout: 2000 }); await expect(page).toHaveScreenshot('foo.png', { timeout: 2000 });
// Anonymous expectation. // Anonymous expectation.
@ -216,7 +224,8 @@ test('should not fail when racing with navigation', async ({ runInlineTest }, te
}), }),
'__screenshots__/a.spec.js/snapshot.png': createImage(10, 10, 255, 0, 0), '__screenshots__/a.spec.js/snapshot.png': createImage(10, 10, 255, 0, 0),
'a.spec.js': ` 'a.spec.js': `
pwt.test('is a test', async ({ page }) => { const { test, expect } = require('@playwright/test');
test('is a test', async ({ page }) => {
await Promise.all([ await Promise.all([
page.goto('${infiniteAnimationURL}'), page.goto('${infiniteAnimationURL}'),
expect(page).toHaveScreenshot({ expect(page).toHaveScreenshot({
@ -238,7 +247,8 @@ test('should successfully screenshot a page with infinite animation with disable
snapshotPathTemplate: '__screenshots__/{testFilePath}/{arg}{ext}', snapshotPathTemplate: '__screenshots__/{testFilePath}/{arg}{ext}',
}), }),
'a.spec.js': ` 'a.spec.js': `
pwt.test('is a test', async ({ page }) => { const { test, expect } = require('@playwright/test');
test('is a test', async ({ page }) => {
await page.goto('${infiniteAnimationURL}'); await page.goto('${infiniteAnimationURL}');
await expect(page).toHaveScreenshot({ await expect(page).toHaveScreenshot({
animations: "disabled", animations: "disabled",
@ -257,7 +267,8 @@ test('should support clip option for page', async ({ runInlineTest }, testInfo)
}), }),
'__screenshots__/a.spec.js/snapshot.png': createImage(50, 50, 255, 255, 255), '__screenshots__/a.spec.js/snapshot.png': createImage(50, 50, 255, 255, 255),
'a.spec.js': ` 'a.spec.js': `
pwt.test('is a test', async ({ page }) => { const { test, expect } = require('@playwright/test');
test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot({ await expect(page).toHaveScreenshot({
name: 'snapshot.png', name: 'snapshot.png',
clip: { x: 0, y: 0, width: 50, height: 50, }, clip: { x: 0, y: 0, width: 50, height: 50, },
@ -274,7 +285,8 @@ test('should support omitBackground option for locator', async ({ runInlineTest
snapshotPathTemplate: '__screenshots__/{testFilePath}/{arg}{ext}', snapshotPathTemplate: '__screenshots__/{testFilePath}/{arg}{ext}',
}), }),
'a.spec.js': ` 'a.spec.js': `
pwt.test('is a test', async ({ page }) => { const { test, expect } = require('@playwright/test');
test('is a test', async ({ page }) => {
await page.evaluate(() => { await page.evaluate(() => {
document.body.style.setProperty('width', '100px'); document.body.style.setProperty('width', '100px');
document.body.style.setProperty('height', '100px'); document.body.style.setProperty('height', '100px');
@ -312,7 +324,8 @@ test('should fail to screenshot an element with infinite animation', async ({ ru
}], }],
}), }),
'a.spec.js': ` 'a.spec.js': `
pwt.test('is a test', async ({ page }) => { const { test, expect } = require('@playwright/test');
test('is a test', async ({ page }) => {
await page.goto('${infiniteAnimationURL}'); await page.goto('${infiniteAnimationURL}');
await expect(page.locator('body')).toHaveScreenshot({ timeout: 2000 }); await expect(page.locator('body')).toHaveScreenshot({ timeout: 2000 });
}); });
@ -340,7 +353,8 @@ test('should fail to screenshot an element that keeps moving', async ({ runInlin
}, },
}), }),
'a.spec.js': ` 'a.spec.js': `
pwt.test('is a test', async ({ page }) => { const { test, expect } = require('@playwright/test');
test('is a test', async ({ page }) => {
await page.goto('${infiniteAnimationURL}'); await page.goto('${infiniteAnimationURL}');
await expect(page.locator('div')).toHaveScreenshot({ timeout: 2000 }); await expect(page.locator('div')).toHaveScreenshot({ timeout: 2000 });
}); });
@ -361,7 +375,8 @@ test('should generate default name', async ({ runInlineTest }, testInfo) => {
snapshotPathTemplate: '__screenshots__/{testFilePath}/{arg}{ext}', snapshotPathTemplate: '__screenshots__/{testFilePath}/{arg}{ext}',
}), }),
'a.spec.js': ` 'a.spec.js': `
pwt.test('is a test', async ({ page }) => { const { test, expect } = require('@playwright/test');
test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot(); await expect(page).toHaveScreenshot();
}); });
` `
@ -374,7 +389,6 @@ test('should generate default name', async ({ runInlineTest }, testInfo) => {
test('should compile with different option combinations', async ({ runTSC }) => { test('should compile with different option combinations', async ({ runTSC }) => {
const result = await runTSC({ const result = await runTSC({
'playwright.config.ts': ` 'playwright.config.ts': `
//@no-header
import { defineConfig } from '@playwright/test'; import { defineConfig } from '@playwright/test';
export default defineConfig({ export default defineConfig({
expect: { expect: {
@ -391,7 +405,7 @@ test('should compile with different option combinations', async ({ runTSC }) =>
}); });
`, `,
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('is a test', async ({ page }) => { test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot(); await expect(page).toHaveScreenshot();
await expect(page).toHaveScreenshot('img.png'); await expect(page).toHaveScreenshot('img.png');
@ -421,7 +435,8 @@ test('should fail when screenshot is different size', async ({ runInlineTest })
}), }),
'__screenshots__/a.spec.js/snapshot.png': createImage(22, 33), '__screenshots__/a.spec.js/snapshot.png': createImage(22, 33),
'a.spec.js': ` 'a.spec.js': `
pwt.test('is a test', async ({ page }) => { const { test, expect } = require('@playwright/test');
test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot('snapshot.png', { timeout: 2000 }); await expect(page).toHaveScreenshot('snapshot.png', { timeout: 2000 });
}); });
` `
@ -438,7 +453,8 @@ test('should fail when given non-png snapshot name', async ({ runInlineTest }) =
snapshotPathTemplate: '__screenshots__/{testFilePath}/{arg}{ext}', snapshotPathTemplate: '__screenshots__/{testFilePath}/{arg}{ext}',
}), }),
'a.spec.js': ` 'a.spec.js': `
pwt.test('is a test', async ({ page }) => { const { test, expect } = require('@playwright/test');
test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot('snapshot.jpeg'); await expect(page).toHaveScreenshot('snapshot.jpeg');
}); });
` `
@ -451,7 +467,8 @@ test('should fail when given buffer', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
...playwrightConfig({}), ...playwrightConfig({}),
'a.spec.js': ` 'a.spec.js': `
pwt.test('is a test', async ({ page }) => { const { test, expect } = require('@playwright/test');
test('is a test', async ({ page }) => {
await expect(Buffer.from([1])).toHaveScreenshot(); await expect(Buffer.from([1])).toHaveScreenshot();
}); });
` `
@ -467,7 +484,8 @@ test('should fail when screenshot is different pixels', async ({ runInlineTest }
}), }),
'__screenshots__/a.spec.js/snapshot.png': paintBlackPixels(whiteImage, 12345), '__screenshots__/a.spec.js/snapshot.png': paintBlackPixels(whiteImage, 12345),
'a.spec.js': ` 'a.spec.js': `
pwt.test('is a test', async ({ page }) => { const { test, expect } = require('@playwright/test');
test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot('snapshot.png', { timeout: 2000 }); await expect(page).toHaveScreenshot('snapshot.png', { timeout: 2000 });
}); });
` `
@ -488,7 +506,8 @@ test('doesn\'t create comparison artifacts in an output folder for passed negate
}), }),
'__screenshots__/a.spec.js/snapshot.png': blueImage, '__screenshots__/a.spec.js/snapshot.png': blueImage,
'a.spec.js': ` 'a.spec.js': `
pwt.test('is a test', async ({ page }) => { const { test, expect } = require('@playwright/test');
test('is a test', async ({ page }) => {
await expect(page).not.toHaveScreenshot('snapshot.png'); await expect(page).not.toHaveScreenshot('snapshot.png');
}); });
` `
@ -511,7 +530,8 @@ test('should fail on same snapshots with negate matcher', async ({ runInlineTest
}), }),
'__screenshots__/a.spec.js/snapshot.png': whiteImage, '__screenshots__/a.spec.js/snapshot.png': whiteImage,
'a.spec.js': ` 'a.spec.js': `
pwt.test('is a test', async ({ page }) => { const { test, expect } = require('@playwright/test');
test('is a test', async ({ page }) => {
await expect(page).not.toHaveScreenshot('snapshot.png', { timeout: 2000 }); await expect(page).not.toHaveScreenshot('snapshot.png', { timeout: 2000 });
}); });
` `
@ -529,7 +549,8 @@ test('should not fail if --ignore-snapshots is passed', async ({ runInlineTest }
}), }),
'__screenshots__/a.spec.js/snapshot.png': redImage, '__screenshots__/a.spec.js/snapshot.png': redImage,
'a.spec.js': ` 'a.spec.js': `
pwt.test('is a test', async ({ page }) => { const { test, expect } = require('@playwright/test');
test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot('snapshot.png', { timeout: 2000 }); await expect(page).toHaveScreenshot('snapshot.png', { timeout: 2000 });
}); });
` `
@ -544,7 +565,8 @@ test('should write missing expectations locally twice and continue', async ({ ru
snapshotPathTemplate: '__screenshots__/{testFilePath}/{arg}{ext}', snapshotPathTemplate: '__screenshots__/{testFilePath}/{arg}{ext}',
}), }),
'a.spec.js': ` 'a.spec.js': `
pwt.test('is a test', async ({ page }) => { const { test, expect } = require('@playwright/test');
test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot('snapshot.png'); await expect(page).toHaveScreenshot('snapshot.png');
await expect(page).toHaveScreenshot('snapshot2.png'); await expect(page).toHaveScreenshot('snapshot2.png');
console.log('Here we are!'); console.log('Here we are!');
@ -576,7 +598,8 @@ test('shouldn\'t write missing expectations locally for negated matcher', async
snapshotPathTemplate: '__screenshots__/{testFilePath}/{arg}{ext}', snapshotPathTemplate: '__screenshots__/{testFilePath}/{arg}{ext}',
}), }),
'a.spec.js': ` 'a.spec.js': `
pwt.test('is a test', async ({ page }) => { const { test, expect } = require('@playwright/test');
test('is a test', async ({ page }) => {
await expect(page).not.toHaveScreenshot('snapshot.png'); await expect(page).not.toHaveScreenshot('snapshot.png');
}); });
` `
@ -595,7 +618,8 @@ test('should update snapshot with the update-snapshots flag', async ({ runInline
}), }),
'__screenshots__/a.spec.js/snapshot.png': blueImage, '__screenshots__/a.spec.js/snapshot.png': blueImage,
'a.spec.js': ` 'a.spec.js': `
pwt.test('is a test', async ({ page }) => { const { test, expect } = require('@playwright/test');
test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot('snapshot.png'); await expect(page).toHaveScreenshot('snapshot.png');
}); });
` `
@ -615,7 +639,8 @@ test('shouldn\'t update snapshot with the update-snapshots flag for negated matc
}), }),
'__screenshots__/a.spec.js/snapshot.png': EXPECTED_SNAPSHOT, '__screenshots__/a.spec.js/snapshot.png': EXPECTED_SNAPSHOT,
'a.spec.js': ` 'a.spec.js': `
pwt.test('is a test', async ({ page }) => { const { test, expect } = require('@playwright/test');
test('is a test', async ({ page }) => {
await expect(page).not.toHaveScreenshot('snapshot.png'); await expect(page).not.toHaveScreenshot('snapshot.png');
}); });
` `
@ -632,7 +657,8 @@ test('should silently write missing expectations locally with the update-snapsho
snapshotPathTemplate: '__screenshots__/{testFilePath}/{arg}{ext}', snapshotPathTemplate: '__screenshots__/{testFilePath}/{arg}{ext}',
}), }),
'a.spec.js': ` 'a.spec.js': `
pwt.test('is a test', async ({ page }) => { const { test, expect } = require('@playwright/test');
test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot('snapshot.png'); await expect(page).toHaveScreenshot('snapshot.png');
}); });
` `
@ -651,7 +677,8 @@ test('should not write missing expectations locally with the update-snapshots fl
snapshotPathTemplate: '__screenshots__/{testFilePath}/{arg}{ext}', snapshotPathTemplate: '__screenshots__/{testFilePath}/{arg}{ext}',
}), }),
'a.spec.js': ` 'a.spec.js': `
pwt.test('is a test', async ({ page }) => { const { test, expect } = require('@playwright/test');
test('is a test', async ({ page }) => {
await expect(page).not.toHaveScreenshot('snapshot.png'); await expect(page).not.toHaveScreenshot('snapshot.png');
}); });
` `
@ -672,7 +699,8 @@ test('should match multiple snapshots', async ({ runInlineTest }) => {
'__screenshots__/a.spec.js/green.png': greenImage, '__screenshots__/a.spec.js/green.png': greenImage,
'__screenshots__/a.spec.js/blue.png': blueImage, '__screenshots__/a.spec.js/blue.png': blueImage,
'a.spec.js': ` 'a.spec.js': `
pwt.test('is a test', async ({ page }) => { const { test, expect } = require('@playwright/test');
test('is a test', async ({ page }) => {
await Promise.all([ await Promise.all([
page.evaluate(() => document.documentElement.style.setProperty('background', '#f00')), page.evaluate(() => document.documentElement.style.setProperty('background', '#f00')),
expect(page).toHaveScreenshot('red.png'), expect(page).toHaveScreenshot('red.png'),
@ -698,7 +726,8 @@ test('should use provided name', async ({ runInlineTest }) => {
}), }),
'__screenshots__/a.spec.js/provided.png': whiteImage, '__screenshots__/a.spec.js/provided.png': whiteImage,
'a.spec.js': ` 'a.spec.js': `
pwt.test('is a test', async ({ page }) => { const { test, expect } = require('@playwright/test');
test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot('provided.png'); await expect(page).toHaveScreenshot('provided.png');
}); });
` `
@ -713,7 +742,8 @@ test('should use provided name via options', async ({ runInlineTest }) => {
}), }),
'__screenshots__/a.spec.js/provided.png': whiteImage, '__screenshots__/a.spec.js/provided.png': whiteImage,
'a.spec.js': ` 'a.spec.js': `
pwt.test('is a test', async ({ page }) => { const { test, expect } = require('@playwright/test');
test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot({ name: 'provided.png' }); await expect(page).toHaveScreenshot({ name: 'provided.png' });
}); });
` `
@ -731,7 +761,8 @@ test('should respect maxDiffPixels option', async ({ runInlineTest }) => {
}), }),
'__screenshots__/a.spec.js/snapshot.png': EXPECTED_SNAPSHOT, '__screenshots__/a.spec.js/snapshot.png': EXPECTED_SNAPSHOT,
'a.spec.js': ` 'a.spec.js': `
pwt.test('is a test', async ({ page }) => { const { test, expect } = require('@playwright/test');
test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot('snapshot.png', { timeout: 2000 }); await expect(page).toHaveScreenshot('snapshot.png', { timeout: 2000 });
}); });
` `
@ -743,7 +774,8 @@ test('should respect maxDiffPixels option', async ({ runInlineTest }) => {
}), }),
'__screenshots__/a.spec.js/snapshot.png': EXPECTED_SNAPSHOT, '__screenshots__/a.spec.js/snapshot.png': EXPECTED_SNAPSHOT,
'a.spec.js': ` 'a.spec.js': `
pwt.test('is a test', async ({ page }) => { const { test, expect } = require('@playwright/test');
test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot('snapshot.png', { await expect(page).toHaveScreenshot('snapshot.png', {
maxDiffPixels: ${BAD_PIXELS} maxDiffPixels: ${BAD_PIXELS}
}); });
@ -766,7 +798,8 @@ test('should respect maxDiffPixels option', async ({ runInlineTest }) => {
}), }),
'__screenshots__/a.spec.js/snapshot.png': EXPECTED_SNAPSHOT, '__screenshots__/a.spec.js/snapshot.png': EXPECTED_SNAPSHOT,
'a.spec.js': ` 'a.spec.js': `
pwt.test('is a test', async ({ page }) => { const { test, expect } = require('@playwright/test');
test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot('snapshot.png'); await expect(page).toHaveScreenshot('snapshot.png');
}); });
` `
@ -783,7 +816,8 @@ test('should not update screenshot that matches with maxDiffPixels option when -
}), }),
'__screenshots__/a.spec.js/snapshot.png': EXPECTED_SNAPSHOT, '__screenshots__/a.spec.js/snapshot.png': EXPECTED_SNAPSHOT,
'a.spec.js': ` 'a.spec.js': `
pwt.test('is a test', async ({ page }) => { const { test, expect } = require('@playwright/test');
test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot('snapshot.png', { maxDiffPixels: ${BAD_PIXELS} }); await expect(page).toHaveScreenshot('snapshot.png', { maxDiffPixels: ${BAD_PIXELS} });
}); });
` `
@ -811,7 +845,8 @@ test('should satisfy both maxDiffPixelRatio and maxDiffPixels', async ({ runInli
}), }),
'__screenshots__/a.spec.js/snapshot.png': EXPECTED_SNAPSHOT, '__screenshots__/a.spec.js/snapshot.png': EXPECTED_SNAPSHOT,
'a.spec.js': ` 'a.spec.js': `
pwt.test('is a test', async ({ page }) => { const { test, expect } = require('@playwright/test');
test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot('snapshot.png', { timeout: 2000 }); await expect(page).toHaveScreenshot('snapshot.png', { timeout: 2000 });
}); });
` `
@ -823,7 +858,8 @@ test('should satisfy both maxDiffPixelRatio and maxDiffPixels', async ({ runInli
}), }),
'__screenshots__/a.spec.js/snapshot.png': EXPECTED_SNAPSHOT, '__screenshots__/a.spec.js/snapshot.png': EXPECTED_SNAPSHOT,
'a.spec.js': ` 'a.spec.js': `
pwt.test('is a test', async ({ page }) => { const { test, expect } = require('@playwright/test');
test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot('snapshot.png', { await expect(page).toHaveScreenshot('snapshot.png', {
maxDiffPixels: ${Math.floor(BAD_COUNT / 2)}, maxDiffPixels: ${Math.floor(BAD_COUNT / 2)},
maxDiffPixelRatio: ${BAD_RATIO}, maxDiffPixelRatio: ${BAD_RATIO},
@ -839,7 +875,8 @@ test('should satisfy both maxDiffPixelRatio and maxDiffPixels', async ({ runInli
}), }),
'__screenshots__/a.spec.js/snapshot.png': EXPECTED_SNAPSHOT, '__screenshots__/a.spec.js/snapshot.png': EXPECTED_SNAPSHOT,
'a.spec.js': ` 'a.spec.js': `
pwt.test('is a test', async ({ page }) => { const { test, expect } = require('@playwright/test');
test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot('snapshot.png', { await expect(page).toHaveScreenshot('snapshot.png', {
maxDiffPixels: ${BAD_COUNT}, maxDiffPixels: ${BAD_COUNT},
maxDiffPixelRatio: ${BAD_RATIO / 2}, maxDiffPixelRatio: ${BAD_RATIO / 2},
@ -855,7 +892,8 @@ test('should satisfy both maxDiffPixelRatio and maxDiffPixels', async ({ runInli
}), }),
'__screenshots__/a.spec.js/snapshot.png': EXPECTED_SNAPSHOT, '__screenshots__/a.spec.js/snapshot.png': EXPECTED_SNAPSHOT,
'a.spec.js': ` 'a.spec.js': `
pwt.test('is a test', async ({ page }) => { const { test, expect } = require('@playwright/test');
test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot('snapshot.png', { await expect(page).toHaveScreenshot('snapshot.png', {
maxDiffPixels: ${BAD_COUNT}, maxDiffPixels: ${BAD_COUNT},
maxDiffPixelRatio: ${BAD_RATIO}, maxDiffPixelRatio: ${BAD_RATIO},
@ -876,7 +914,8 @@ test('should respect maxDiffPixelRatio option', async ({ runInlineTest }) => {
}), }),
'__screenshots__/a.spec.js/snapshot.png': EXPECTED_SNAPSHOT, '__screenshots__/a.spec.js/snapshot.png': EXPECTED_SNAPSHOT,
'a.spec.js': ` 'a.spec.js': `
pwt.test('is a test', async ({ page }) => { const { test, expect } = require('@playwright/test');
test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot('snapshot.png', { timeout: 2000 }); await expect(page).toHaveScreenshot('snapshot.png', { timeout: 2000 });
}); });
` `
@ -888,7 +927,8 @@ test('should respect maxDiffPixelRatio option', async ({ runInlineTest }) => {
}), }),
'__screenshots__/a.spec.js/snapshot.png': EXPECTED_SNAPSHOT, '__screenshots__/a.spec.js/snapshot.png': EXPECTED_SNAPSHOT,
'a.spec.js': ` 'a.spec.js': `
pwt.test('is a test', async ({ page }) => { const { test, expect } = require('@playwright/test');
test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot('snapshot.png', { await expect(page).toHaveScreenshot('snapshot.png', {
maxDiffPixelRatio: ${BAD_RATIO} maxDiffPixelRatio: ${BAD_RATIO}
}); });
@ -909,7 +949,8 @@ test('should respect maxDiffPixelRatio option', async ({ runInlineTest }) => {
}), }),
'__screenshots__/a.spec.js/snapshot.png': EXPECTED_SNAPSHOT, '__screenshots__/a.spec.js/snapshot.png': EXPECTED_SNAPSHOT,
'a.spec.js': ` 'a.spec.js': `
pwt.test('is a test', async ({ page }) => { const { test, expect } = require('@playwright/test');
test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot('snapshot.png'); await expect(page).toHaveScreenshot('snapshot.png');
}); });
` `
@ -920,7 +961,8 @@ test('should throw for invalid maxDiffPixels values', async ({ runInlineTest })
expect((await runInlineTest({ expect((await runInlineTest({
...playwrightConfig({}), ...playwrightConfig({}),
'a.spec.js': ` 'a.spec.js': `
pwt.test('is a test', async ({ page }) => { const { test, expect } = require('@playwright/test');
test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot({ await expect(page).toHaveScreenshot({
maxDiffPixels: -1, maxDiffPixels: -1,
}); });
@ -933,7 +975,8 @@ test('should throw for invalid maxDiffPixelRatio values', async ({ runInlineTest
expect((await runInlineTest({ expect((await runInlineTest({
...playwrightConfig({}), ...playwrightConfig({}),
'a.spec.js': ` 'a.spec.js': `
pwt.test('is a test', async ({ page }) => { const { test, expect } = require('@playwright/test');
test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot({ await expect(page).toHaveScreenshot({
maxDiffPixelRatio: 12, maxDiffPixelRatio: 12,
}); });
@ -950,10 +993,11 @@ test('should attach expected/actual/diff when sizes are different', async ({ run
}), }),
'__screenshots__/a.spec.js/snapshot.png': createImage(2, 2), '__screenshots__/a.spec.js/snapshot.png': createImage(2, 2),
'a.spec.js': ` 'a.spec.js': `
pwt.test.afterEach(async ({}, testInfo) => { const { test, expect } = require('@playwright/test');
test.afterEach(async ({}, testInfo) => {
console.log('## ' + JSON.stringify(testInfo.attachments)); console.log('## ' + JSON.stringify(testInfo.attachments));
}); });
pwt.test('is a test', async ({ page }) => { test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot('snapshot.png', { timeout: 2000 }); await expect(page).toHaveScreenshot('snapshot.png', { timeout: 2000 });
}); });
` `
@ -992,7 +1036,8 @@ test('should fail with missing expectations and retries', async ({ runInlineTest
snapshotPathTemplate: '__screenshots__/{testFilePath}/{arg}{ext}', snapshotPathTemplate: '__screenshots__/{testFilePath}/{arg}{ext}',
}), }),
'a.spec.js': ` 'a.spec.js': `
pwt.test('is a test', async ({ page }) => { const { test, expect } = require('@playwright/test');
test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot('snapshot.png'); await expect(page).toHaveScreenshot('snapshot.png');
}); });
` `
@ -1013,7 +1058,8 @@ test('should update expectations with retries', async ({ runInlineTest }, testIn
snapshotPathTemplate: '__screenshots__/{testFilePath}/{arg}{ext}', snapshotPathTemplate: '__screenshots__/{testFilePath}/{arg}{ext}',
}), }),
'a.spec.js': ` 'a.spec.js': `
pwt.test('is a test', async ({ page }) => { const { test, expect } = require('@playwright/test');
test('is a test', async ({ page }) => {
await expect(page).toHaveScreenshot('snapshot.png'); await expect(page).toHaveScreenshot('snapshot.png');
}); });
` `
@ -1036,14 +1082,15 @@ test('should respect comparator name', async ({ runInlineTest }) => {
}), }),
'__screenshots__/a.spec.js/snapshot.png': expected, '__screenshots__/a.spec.js/snapshot.png': expected,
'a.spec.js': ` 'a.spec.js': `
pwt.test('should pass', async ({ page }) => { const { test, expect } = require('@playwright/test');
test('should pass', async ({ page }) => {
await page.goto('${actualURL}'); await page.goto('${actualURL}');
await expect(page.locator('img')).toHaveScreenshot('snapshot.png', { await expect(page.locator('img')).toHaveScreenshot('snapshot.png', {
threshold: 0, threshold: 0,
_comparator: 'ssim-cie94', _comparator: 'ssim-cie94',
}); });
}); });
pwt.test('should fail', async ({ page }) => { test('should fail', async ({ page }) => {
await page.goto('${actualURL}'); await page.goto('${actualURL}');
await expect(page.locator('img')).toHaveScreenshot('snapshot.png', { await expect(page.locator('img')).toHaveScreenshot('snapshot.png', {
threshold: 0, threshold: 0,
@ -1086,7 +1133,8 @@ test('should respect comparator in config', async ({ runInlineTest }) => {
}), }),
'__screenshots__/a.spec.js/snapshot.png': expected, '__screenshots__/a.spec.js/snapshot.png': expected,
'a.spec.js': ` 'a.spec.js': `
pwt.test('test', async ({ page }) => { const { test, expect } = require('@playwright/test');
test('test', async ({ page }) => {
await page.goto('${actualURL}'); await page.goto('${actualURL}');
await expect(page.locator('img')).toHaveScreenshot('snapshot.png', { threshold: 0, }); await expect(page.locator('img')).toHaveScreenshot('snapshot.png', { threshold: 0, });
}); });

View File

@ -19,7 +19,7 @@ import { test, expect } from './playwright-test-fixtures';
test('basics should work', async ({ runTSC }) => { test('basics should work', async ({ runTSC }) => {
const result = await runTSC({ const result = await runTSC({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.describe('suite', () => { test.describe('suite', () => {
test.beforeEach(async () => {}); test.beforeEach(async () => {});
test.afterEach(async () => {}); test.afterEach(async () => {});
@ -54,7 +54,8 @@ test('basics should work', async ({ runTSC }) => {
test('can pass sync functions everywhere', async ({ runTSC }) => { test('can pass sync functions everywhere', async ({ runTSC }) => {
const result = await runTSC({ const result = await runTSC({
'a.spec.ts': ` 'a.spec.ts': `
const test = pwt.test.extend<{ foo: string }>({ import { test as base, expect } from '@playwright/test';
const test = base.extend<{ foo: string }>({
foo: ({}, use) => use('bar'), foo: ({}, use) => use('bar'),
}); });
test.beforeEach(({ foo }) => {}); test.beforeEach(({ foo }) => {});
@ -70,7 +71,7 @@ test('can pass sync functions everywhere', async ({ runTSC }) => {
test('can return anything from hooks', async ({ runTSC }) => { test('can return anything from hooks', async ({ runTSC }) => {
const result = await runTSC({ const result = await runTSC({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test.beforeEach(() => '123'); test.beforeEach(() => '123');
test.afterEach(() => 123); test.afterEach(() => 123);
test.beforeAll(() => [123]); test.beforeAll(() => [123]);
@ -83,8 +84,9 @@ test('can return anything from hooks', async ({ runTSC }) => {
test('test.extend options should check types', async ({ runTSC }) => { test('test.extend options should check types', async ({ runTSC }) => {
const result = await runTSC({ const result = await runTSC({
'helper.ts': ` 'helper.ts': `
import { test as base, expect } from '@playwright/test';
export type Params = { foo: string }; export type Params = { foo: string };
export const test = pwt.test; export const test = base;
export const test1 = test.extend<Params>({ foo: [ 'foo', { option: true } ] }); export const test1 = test.extend<Params>({ foo: [ 'foo', { option: true } ] });
export const test1b = test.extend<{ bar: string }>({ bar: [ 'bar', { option: true } ] }); export const test1b = test.extend<{ bar: string }>({ bar: [ 'bar', { option: true } ] });
export const testerror = test.extend<{ foo: string }>({ export const testerror = test.extend<{ foo: string }>({
@ -104,7 +106,8 @@ test('test.extend options should check types', async ({ runTSC }) => {
`, `,
'playwright.config.ts': ` 'playwright.config.ts': `
import { Params } from './helper'; import { Params } from './helper';
const configs: pwt.Config<Params>[] = []; import { Config } from '@playwright/test';
const configs: Config<Params>[] = [];
configs.push({}); configs.push({});
@ -143,7 +146,7 @@ test('test.extend options should check types', async ({ runTSC }) => {
test('step should inherit return type from its callback ', async ({ runTSC }) => { test('step should inherit return type from its callback ', async ({ runTSC }) => {
const result = await runTSC({ const result = await runTSC({
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('my test', async ({ }) => { test('my test', async ({ }) => {
// @ts-expect-error // @ts-expect-error
const bad1: string = await test.step('my step', () => { const bad1: string = await test.step('my step', () => {

View File

@ -19,8 +19,9 @@ import { test, expect } from './playwright-test-fixtures';
test('should check types of fixtures', async ({ runTSC }) => { test('should check types of fixtures', async ({ runTSC }) => {
const result = await runTSC({ const result = await runTSC({
'helper.ts': ` 'helper.ts': `
import { test as base, expect } from '@playwright/test';
export type MyOptions = { foo: string, bar: number }; export type MyOptions = { foo: string, bar: number };
export const test = pwt.test.extend<{ foo: string }, { bar: number }>({ export const test = base.extend<{ foo: string }, { bar: number }>({
foo: 'foo', foo: 'foo',
bar: [ 42, { scope: 'worker', timeout: 123 } ], bar: [ 42, { scope: 'worker', timeout: 123 } ],
}); });
@ -91,7 +92,7 @@ test('should check types of fixtures', async ({ runTSC }) => {
type AssertNotAny<S> = {notRealProperty: number} extends S ? false : true; type AssertNotAny<S> = {notRealProperty: number} extends S ? false : true;
type AssertType<T, S> = S extends T ? AssertNotAny<S> : false; type AssertType<T, S> = S extends T ? AssertNotAny<S> : false;
const funcTest = pwt.test.extend<{ foo: (x: number, y: string) => Promise<string> }>({ const funcTest = base.extend<{ foo: (x: number, y: string) => Promise<string> }>({
foo: async ({}, use) => { foo: async ({}, use) => {
await use(async (x, y) => { await use(async (x, y) => {
const assertionX: AssertType<number, typeof x> = true; const assertionX: AssertType<number, typeof x> = true;
@ -103,15 +104,14 @@ test('should check types of fixtures', async ({ runTSC }) => {
`, `,
'playwright.config.ts': ` 'playwright.config.ts': `
import { MyOptions } from './helper'; import { MyOptions } from './helper';
const configs1: pwt.Config[] = []; import { Config } from '@playwright/test';
const configs1: Config[] = [];
configs1.push({ use: { foo: '42', bar: 42 } }); configs1.push({ use: { foo: '42', bar: 42 } });
configs1.push({ use: { foo: '42', bar: 42 }, timeout: 100 }); configs1.push({ use: { foo: '42', bar: 42 }, timeout: 100 });
const configs2: pwt.Config<MyOptions>[] = []; const configs2: Config<MyOptions>[] = [];
configs2.push({ use: { foo: '42', bar: 42 } }); configs2.push({ use: { foo: '42', bar: 42 } });
// @ts-expect-error // @ts-expect-error
pwt.runTests({ use: { foo: '42', bar: 42 } }, {});
// @ts-expect-error
configs2.push({ use: { bar: '42' } }); configs2.push({ use: { bar: '42' } });
// @ts-expect-error // @ts-expect-error
configs2.push(new Env2()); configs2.push(new Env2());
@ -168,7 +168,8 @@ test('should check types of fixtures', async ({ runTSC }) => {
test.afterAll(() => {}); test.afterAll(() => {});
`, `,
'playwright-props.config.ts': ` 'playwright-props.config.ts': `
const config0: pwt.PlaywrightTestConfig = { import { PlaywrightTestConfig } from '@playwright/test';
const config0: PlaywrightTestConfig = {
use: { use: {
ignoreHTTPSErrors: undefined, ignoreHTTPSErrors: undefined,
isMobile: true, isMobile: true,
@ -176,7 +177,7 @@ test('should check types of fixtures', async ({ runTSC }) => {
}, },
}; };
const config1: pwt.PlaywrightTestConfig = { const config1: PlaywrightTestConfig = {
use: { use: {
ignoreHTTPSErrors: undefined, ignoreHTTPSErrors: undefined,
isMobile: true, isMobile: true,
@ -186,7 +187,7 @@ test('should check types of fixtures', async ({ runTSC }) => {
}, },
}; };
const config2: pwt.PlaywrightTestConfig = { const config2: PlaywrightTestConfig = {
use: { use: {
ignoreHTTPSErrors: undefined, ignoreHTTPSErrors: undefined,
isMobile: true, isMobile: true,
@ -196,7 +197,7 @@ test('should check types of fixtures', async ({ runTSC }) => {
}, },
}; };
const config3: pwt.PlaywrightTestConfig<{ foo: boolean }> = { const config3: PlaywrightTestConfig<{ foo: boolean }> = {
use: { use: {
ignoreHTTPSErrors: undefined, ignoreHTTPSErrors: undefined,
isMobile: true, isMobile: true,
@ -205,7 +206,7 @@ test('should check types of fixtures', async ({ runTSC }) => {
}, },
}; };
const config4: pwt.PlaywrightTestConfig<{ foo: boolean }> = { const config4: PlaywrightTestConfig<{ foo: boolean }> = {
use: { use: {
ignoreHTTPSErrors: undefined, ignoreHTTPSErrors: undefined,
isMobile: true, isMobile: true,
@ -218,7 +219,8 @@ test('should check types of fixtures', async ({ runTSC }) => {
`, `,
'playwright-define.config.ts': ` 'playwright-define.config.ts': `
const config0 = pwt.defineConfig({ import { defineConfig } from '@playwright/test';
const config0 = defineConfig({
use: { use: {
ignoreHTTPSErrors: undefined, ignoreHTTPSErrors: undefined,
isMobile: true, isMobile: true,
@ -226,7 +228,7 @@ test('should check types of fixtures', async ({ runTSC }) => {
}, },
}); });
const config1 = pwt.defineConfig({ const config1 = defineConfig({
use: { use: {
ignoreHTTPSErrors: undefined, ignoreHTTPSErrors: undefined,
isMobile: true, isMobile: true,
@ -236,7 +238,7 @@ test('should check types of fixtures', async ({ runTSC }) => {
}, },
}); });
const config2 = pwt.defineConfig({ const config2 = defineConfig({
use: { use: {
ignoreHTTPSErrors: undefined, ignoreHTTPSErrors: undefined,
isMobile: true, isMobile: true,
@ -246,7 +248,7 @@ test('should check types of fixtures', async ({ runTSC }) => {
}, },
}); });
const config3 = pwt.defineConfig<{ foo: boolean }>({ const config3 = defineConfig<{ foo: boolean }>({
use: { use: {
ignoreHTTPSErrors: undefined, ignoreHTTPSErrors: undefined,
isMobile: true, isMobile: true,
@ -255,7 +257,7 @@ test('should check types of fixtures', async ({ runTSC }) => {
}, },
}); });
const config4 = pwt.defineConfig<{ foo: boolean }>({ const config4 = defineConfig<{ foo: boolean }>({
use: { use: {
ignoreHTTPSErrors: undefined, ignoreHTTPSErrors: undefined,
isMobile: true, isMobile: true,
@ -273,14 +275,15 @@ test('should check types of fixtures', async ({ runTSC }) => {
test('config should allow void/empty options', async ({ runTSC }) => { test('config should allow void/empty options', async ({ runTSC }) => {
const result = await runTSC({ const result = await runTSC({
'playwright.config.ts': ` 'playwright.config.ts': `
const configs: pwt.Config[] = []; import { Config } from '@playwright/test';
const configs: Config[] = [];
configs.push({}); configs.push({});
configs.push({ timeout: 100 }); configs.push({ timeout: 100 });
configs.push(); configs.push();
configs.push({ use: { foo: 42 }}); configs.push({ use: { foo: 42 }});
`, `,
'a.spec.ts': ` 'a.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('my test', async () => { test('my test', async () => {
}); });
` `

View File

@ -31,11 +31,13 @@ test('should print dependencies in CJS mode', async ({ runInlineTest }) => {
'helperB.ts': `import './helperA';`, 'helperB.ts': `import './helperA';`,
'a.test.ts': ` 'a.test.ts': `
import './helperA'; import './helperA';
pwt.test('passes', () => {}); import { test, expect } from '@playwright/test';
test('passes', () => {});
`, `,
'b.test.ts': ` 'b.test.ts': `
import './helperB'; import './helperB';
pwt.test('passes', () => {}); import { test, expect } from '@playwright/test';
test('passes', () => {});
`, `,
'globalTeardown.ts': ` 'globalTeardown.ts': `
import { fileDependencies } from '@playwright/test/lib/internalsForTest'; import { fileDependencies } from '@playwright/test/lib/internalsForTest';
@ -69,11 +71,13 @@ test('should print dependencies in ESM mode', async ({ runInlineTest, nodeVersio
'helperB.ts': `import './helperA.js';`, 'helperB.ts': `import './helperA.js';`,
'a.test.ts': ` 'a.test.ts': `
import './helperA.js'; import './helperA.js';
pwt.test('passes', () => {}); import { test, expect } from '@playwright/test';
test('passes', () => {});
`, `,
'b.test.ts': ` 'b.test.ts': `
import './helperB.js'; import './helperB.js';
pwt.test('passes', () => {}); import { test, expect } from '@playwright/test';
test('passes', () => {});
`, `,
'globalTeardown.ts': ` 'globalTeardown.ts': `
import { fileDependencies } from '@playwright/test/lib/internalsForTest'; import { fileDependencies } from '@playwright/test/lib/internalsForTest';
@ -96,10 +100,11 @@ test('should print dependencies in ESM mode', async ({ runInlineTest, nodeVersio
test('should perform initial run', async ({ runWatchTest }) => { test('should perform initial run', async ({ runWatchTest }) => {
const testProcess = await runWatchTest({ const testProcess = await runWatchTest({
'a.test.ts': ` 'a.test.ts': `
pwt.test('passes', () => {}); import { test, expect } from '@playwright/test';
test('passes', () => {});
`, `,
}, {}); }, {});
await testProcess.waitForOutput('a.test.ts:5:11 passes'); await testProcess.waitForOutput('a.test.ts:3:11 passes');
await testProcess.waitForOutput('Waiting for file changes.'); await testProcess.waitForOutput('Waiting for file changes.');
}); });
@ -120,76 +125,83 @@ test('should print help on H', async ({ runWatchTest }) => {
test('should run tests on Enter', async ({ runWatchTest }) => { test('should run tests on Enter', async ({ runWatchTest }) => {
const testProcess = await runWatchTest({ const testProcess = await runWatchTest({
'a.test.ts': ` 'a.test.ts': `
pwt.test('passes', () => {}); import { test, expect } from '@playwright/test';
test('passes', () => {});
`, `,
}, {}); }, {});
await testProcess.waitForOutput('a.test.ts:5:11 passes'); await testProcess.waitForOutput('a.test.ts:3:11 passes');
await testProcess.waitForOutput('Waiting for file changes.'); await testProcess.waitForOutput('Waiting for file changes.');
testProcess.clearOutput(); testProcess.clearOutput();
testProcess.write('\r\n'); testProcess.write('\r\n');
await testProcess.waitForOutput('npx playwright test #1'); await testProcess.waitForOutput('npx playwright test #1');
await testProcess.waitForOutput('a.test.ts:5:11 passes'); await testProcess.waitForOutput('a.test.ts:3:11 passes');
await testProcess.waitForOutput('Waiting for file changes.'); await testProcess.waitForOutput('Waiting for file changes.');
}); });
test('should run tests on R', async ({ runWatchTest }) => { test('should run tests on R', async ({ runWatchTest }) => {
const testProcess = await runWatchTest({ const testProcess = await runWatchTest({
'a.test.ts': ` 'a.test.ts': `
pwt.test('passes', () => {}); import { test, expect } from '@playwright/test';
test('passes', () => {});
`, `,
}, {}); }, {});
await testProcess.waitForOutput('a.test.ts:5:11 passes'); await testProcess.waitForOutput('a.test.ts:3:11 passes');
await testProcess.waitForOutput('Waiting for file changes.'); await testProcess.waitForOutput('Waiting for file changes.');
testProcess.clearOutput(); testProcess.clearOutput();
testProcess.write('r'); testProcess.write('r');
await testProcess.waitForOutput('npx playwright test (re-running tests) #1'); await testProcess.waitForOutput('npx playwright test (re-running tests) #1');
await testProcess.waitForOutput('a.test.ts:5:11 passes'); await testProcess.waitForOutput('a.test.ts:3:11 passes');
await testProcess.waitForOutput('Waiting for file changes.'); await testProcess.waitForOutput('Waiting for file changes.');
}); });
test('should run failed tests on F', async ({ runWatchTest }) => { test('should run failed tests on F', async ({ runWatchTest }) => {
const testProcess = await runWatchTest({ const testProcess = await runWatchTest({
'a.test.ts': ` 'a.test.ts': `
pwt.test('passes', () => {}); import { test, expect } from '@playwright/test';
test('passes', () => {});
`, `,
'b.test.ts': ` 'b.test.ts': `
pwt.test('passes', () => {}); import { test, expect } from '@playwright/test';
test('passes', () => {});
`, `,
'c.test.ts': ` 'c.test.ts': `
pwt.test('fails', () => { expect(1).toBe(2); }); import { test, expect } from '@playwright/test';
test('fails', () => { expect(1).toBe(2); });
`, `,
}, {}); }, {});
await testProcess.waitForOutput('a.test.ts:5:11 passes'); await testProcess.waitForOutput('a.test.ts:3:11 passes');
await testProcess.waitForOutput('b.test.ts:5:11 passes'); await testProcess.waitForOutput('b.test.ts:3:11 passes');
await testProcess.waitForOutput('c.test.ts:5:11 fails'); await testProcess.waitForOutput('c.test.ts:3:11 fails');
await testProcess.waitForOutput('Error: expect(received).toBe(expected)'); await testProcess.waitForOutput('Error: expect(received).toBe(expected)');
await testProcess.waitForOutput('Waiting for file changes.'); await testProcess.waitForOutput('Waiting for file changes.');
testProcess.clearOutput(); testProcess.clearOutput();
testProcess.write('f'); testProcess.write('f');
await testProcess.waitForOutput('npx playwright test (running failed tests) #1'); await testProcess.waitForOutput('npx playwright test (running failed tests) #1');
await testProcess.waitForOutput('c.test.ts:5:11 fails'); await testProcess.waitForOutput('c.test.ts:3:11 fails');
expect(testProcess.output).not.toContain('a.test.ts:5:11'); expect(testProcess.output).not.toContain('a.test.ts:3:11');
}); });
test('should respect file filter P', async ({ runWatchTest }) => { test('should respect file filter P', async ({ runWatchTest }) => {
const testProcess = await runWatchTest({ const testProcess = await runWatchTest({
'a.test.ts': ` 'a.test.ts': `
pwt.test('passes', () => {}); import { test, expect } from '@playwright/test';
test('passes', () => {});
`, `,
'b.test.ts': ` 'b.test.ts': `
pwt.test('passes', () => {}); import { test, expect } from '@playwright/test';
test('passes', () => {});
`, `,
}, {}); }, {});
await testProcess.waitForOutput('a.test.ts:5:11 passes'); await testProcess.waitForOutput('a.test.ts:3:11 passes');
await testProcess.waitForOutput('b.test.ts:5:11 passes'); await testProcess.waitForOutput('b.test.ts:3:11 passes');
await testProcess.waitForOutput('Waiting for file changes.'); await testProcess.waitForOutput('Waiting for file changes.');
testProcess.clearOutput(); testProcess.clearOutput();
testProcess.write('p'); testProcess.write('p');
await testProcess.waitForOutput('Input filename pattern (regex)'); await testProcess.waitForOutput('Input filename pattern (regex)');
testProcess.write('b.test\r\n'); testProcess.write('b.test\r\n');
await testProcess.waitForOutput('npx playwright test b.test #1'); await testProcess.waitForOutput('npx playwright test b.test #1');
await testProcess.waitForOutput('b.test.ts:5:11 passes'); await testProcess.waitForOutput('b.test.ts:3:11 passes');
expect(testProcess.output).not.toContain('a.test.ts:5:11'); expect(testProcess.output).not.toContain('a.test.ts:3:11');
await testProcess.waitForOutput('Waiting for file changes.'); await testProcess.waitForOutput('Waiting for file changes.');
}); });
@ -200,11 +212,12 @@ test('should respect project filter C', async ({ runWatchTest }) => {
export default defineConfig({ projects: [{name: 'foo'}, {name: 'bar'}] }); export default defineConfig({ projects: [{name: 'foo'}, {name: 'bar'}] });
`, `,
'a.test.ts': ` 'a.test.ts': `
pwt.test('passes', () => {}); import { test, expect } from '@playwright/test';
test('passes', () => {});
`, `,
}, {}); }, {});
await testProcess.waitForOutput('[foo] a.test.ts:5:11 passes'); await testProcess.waitForOutput('[foo] a.test.ts:3:11 passes');
await testProcess.waitForOutput('[bar] a.test.ts:5:11 passes'); await testProcess.waitForOutput('[bar] a.test.ts:3:11 passes');
await testProcess.waitForOutput('Waiting for file changes.'); await testProcess.waitForOutput('Waiting for file changes.');
testProcess.clearOutput(); testProcess.clearOutput();
testProcess.write('c'); testProcess.write('c');
@ -214,127 +227,140 @@ test('should respect project filter C', async ({ runWatchTest }) => {
testProcess.write(' '); testProcess.write(' ');
testProcess.write('\r\n'); testProcess.write('\r\n');
await testProcess.waitForOutput('npx playwright test --project foo #1'); await testProcess.waitForOutput('npx playwright test --project foo #1');
await testProcess.waitForOutput('[foo] a.test.ts:5:11 passes'); await testProcess.waitForOutput('[foo] a.test.ts:3:11 passes');
expect(testProcess.output).not.toContain('[bar] a.test.ts:5:11 passes'); expect(testProcess.output).not.toContain('[bar] a.test.ts:3:11 passes');
}); });
test('should respect file filter P and split files', async ({ runWatchTest }) => { test('should respect file filter P and split files', async ({ runWatchTest }) => {
const testProcess = await runWatchTest({ const testProcess = await runWatchTest({
'a.test.ts': ` 'a.test.ts': `
pwt.test('passes', () => {}); import { test, expect } from '@playwright/test';
test('passes', () => {});
`, `,
'b.test.ts': ` 'b.test.ts': `
pwt.test('passes', () => {}); import { test, expect } from '@playwright/test';
test('passes', () => {});
`, `,
}, {}); }, {});
await testProcess.waitForOutput('a.test.ts:5:11 passes'); await testProcess.waitForOutput('a.test.ts:3:11 passes');
await testProcess.waitForOutput('b.test.ts:5:11 passes'); await testProcess.waitForOutput('b.test.ts:3:11 passes');
await testProcess.waitForOutput('Waiting for file changes.'); await testProcess.waitForOutput('Waiting for file changes.');
testProcess.clearOutput(); testProcess.clearOutput();
testProcess.write('p'); testProcess.write('p');
await testProcess.waitForOutput('Input filename pattern (regex)'); await testProcess.waitForOutput('Input filename pattern (regex)');
testProcess.write('a.test b.test\r\n'); testProcess.write('a.test b.test\r\n');
await testProcess.waitForOutput('npx playwright test a.test b.test #1'); await testProcess.waitForOutput('npx playwright test a.test b.test #1');
await testProcess.waitForOutput('a.test.ts:5:11 passes'); await testProcess.waitForOutput('a.test.ts:3:11 passes');
await testProcess.waitForOutput('b.test.ts:5:11 passes'); await testProcess.waitForOutput('b.test.ts:3:11 passes');
await testProcess.waitForOutput('Waiting for file changes.'); await testProcess.waitForOutput('Waiting for file changes.');
}); });
test('should respect title filter T', async ({ runWatchTest }) => { test('should respect title filter T', async ({ runWatchTest }) => {
const testProcess = await runWatchTest({ const testProcess = await runWatchTest({
'a.test.ts': ` 'a.test.ts': `
pwt.test('title 1', () => {}); import { test, expect } from '@playwright/test';
test('title 1', () => {});
`, `,
'b.test.ts': ` 'b.test.ts': `
pwt.test('title 2', () => {}); import { test, expect } from '@playwright/test';
test('title 2', () => {});
`, `,
}, {}); }, {});
await testProcess.waitForOutput('a.test.ts:5:11 title 1'); await testProcess.waitForOutput('a.test.ts:3:11 title 1');
await testProcess.waitForOutput('b.test.ts:5:11 title 2'); await testProcess.waitForOutput('b.test.ts:3:11 title 2');
await testProcess.waitForOutput('Waiting for file changes.'); await testProcess.waitForOutput('Waiting for file changes.');
testProcess.clearOutput(); testProcess.clearOutput();
testProcess.write('t'); testProcess.write('t');
await testProcess.waitForOutput('Input test name pattern (regex)'); await testProcess.waitForOutput('Input test name pattern (regex)');
testProcess.write('title 2\r\n'); testProcess.write('title 2\r\n');
await testProcess.waitForOutput('npx playwright test --grep title 2 #1'); await testProcess.waitForOutput('npx playwright test --grep title 2 #1');
await testProcess.waitForOutput('b.test.ts:5:11 title 2'); await testProcess.waitForOutput('b.test.ts:3:11 title 2');
expect(testProcess.output).not.toContain('a.test.ts:5:11'); expect(testProcess.output).not.toContain('a.test.ts:3:11');
await testProcess.waitForOutput('Waiting for file changes.'); await testProcess.waitForOutput('Waiting for file changes.');
}); });
test('should re-run failed tests on F > R', async ({ runWatchTest }) => { test('should re-run failed tests on F > R', async ({ runWatchTest }) => {
const testProcess = await runWatchTest({ const testProcess = await runWatchTest({
'a.test.ts': ` 'a.test.ts': `
pwt.test('passes', () => {}); import { test, expect } from '@playwright/test';
test('passes', () => {});
`, `,
'b.test.ts': ` 'b.test.ts': `
pwt.test('passes', () => {}); import { test, expect } from '@playwright/test';
test('passes', () => {});
`, `,
'c.test.ts': ` 'c.test.ts': `
pwt.test('fails', () => { expect(1).toBe(2); }); import { test, expect } from '@playwright/test';
test('fails', () => { expect(1).toBe(2); });
`, `,
}, {}); }, {});
await testProcess.waitForOutput('a.test.ts:5:11 passes'); await testProcess.waitForOutput('a.test.ts:3:11 passes');
await testProcess.waitForOutput('b.test.ts:5:11 passes'); await testProcess.waitForOutput('b.test.ts:3:11 passes');
await testProcess.waitForOutput('c.test.ts:5:11 fails'); await testProcess.waitForOutput('c.test.ts:3:11 fails');
await testProcess.waitForOutput('Error: expect(received).toBe(expected)'); await testProcess.waitForOutput('Error: expect(received).toBe(expected)');
await testProcess.waitForOutput('Waiting for file changes.'); await testProcess.waitForOutput('Waiting for file changes.');
testProcess.clearOutput(); testProcess.clearOutput();
testProcess.write('f'); testProcess.write('f');
await testProcess.waitForOutput('npx playwright test (running failed tests) #1'); await testProcess.waitForOutput('npx playwright test (running failed tests) #1');
await testProcess.waitForOutput('c.test.ts:5:11 fails'); await testProcess.waitForOutput('c.test.ts:3:11 fails');
expect(testProcess.output).not.toContain('a.test.ts:5:11'); expect(testProcess.output).not.toContain('a.test.ts:3:11');
testProcess.clearOutput(); testProcess.clearOutput();
testProcess.write('r'); testProcess.write('r');
await testProcess.waitForOutput('npx playwright test (re-running tests) #2'); await testProcess.waitForOutput('npx playwright test (re-running tests) #2');
await testProcess.waitForOutput('c.test.ts:5:11 fails'); await testProcess.waitForOutput('c.test.ts:3:11 fails');
expect(testProcess.output).not.toContain('a.test.ts:5:11'); expect(testProcess.output).not.toContain('a.test.ts:3:11');
}); });
test('should run on changed files', async ({ runWatchTest, writeFiles }) => { test('should run on changed files', async ({ runWatchTest, writeFiles }) => {
const testProcess = await runWatchTest({ const testProcess = await runWatchTest({
'a.test.ts': ` 'a.test.ts': `
pwt.test('passes', () => {}); import { test, expect } from '@playwright/test';
test('passes', () => {});
`, `,
'b.test.ts': ` 'b.test.ts': `
pwt.test('passes', () => {}); import { test, expect } from '@playwright/test';
test('passes', () => {});
`, `,
'c.test.ts': ` 'c.test.ts': `
pwt.test('fails', () => { expect(1).toBe(2); }); import { test, expect } from '@playwright/test';
test('fails', () => { expect(1).toBe(2); });
`, `,
}, {}); }, {});
await testProcess.waitForOutput('a.test.ts:5:11 passes'); await testProcess.waitForOutput('a.test.ts:3:11 passes');
await testProcess.waitForOutput('b.test.ts:5:11 passes'); await testProcess.waitForOutput('b.test.ts:3:11 passes');
await testProcess.waitForOutput('c.test.ts:5:11 fails'); await testProcess.waitForOutput('c.test.ts:3:11 fails');
await testProcess.waitForOutput('Error: expect(received).toBe(expected)'); await testProcess.waitForOutput('Error: expect(received).toBe(expected)');
await testProcess.waitForOutput('Waiting for file changes.'); await testProcess.waitForOutput('Waiting for file changes.');
testProcess.clearOutput(); testProcess.clearOutput();
await writeFiles({ await writeFiles({
'c.test.ts': ` 'c.test.ts': `
pwt.test('passes', () => {}); import { test, expect } from '@playwright/test';
test('passes', () => {});
`, `,
}); });
await testProcess.waitForOutput('c.test.ts:5:11 passes'); await testProcess.waitForOutput('c.test.ts:3:11 passes');
expect(testProcess.output).not.toContain('a.test.ts:5:11 passes'); expect(testProcess.output).not.toContain('a.test.ts:3:11 passes');
expect(testProcess.output).not.toContain('b.test.ts:5:11 passes'); expect(testProcess.output).not.toContain('b.test.ts:3:11 passes');
await testProcess.waitForOutput('Waiting for file changes.'); await testProcess.waitForOutput('Waiting for file changes.');
}); });
test('should run on changed deps', async ({ runWatchTest, writeFiles }) => { test('should run on changed deps', async ({ runWatchTest, writeFiles }) => {
const testProcess = await runWatchTest({ const testProcess = await runWatchTest({
'a.test.ts': ` 'a.test.ts': `
pwt.test('passes', () => {}); import { test, expect } from '@playwright/test';
test('passes', () => {});
`, `,
'b.test.ts': ` 'b.test.ts': `
import './helper'; import './helper';
pwt.test('passes', () => {}); import { test, expect } from '@playwright/test';
test('passes', () => {});
`, `,
'helper.ts': ` 'helper.ts': `
console.log('old helper'); console.log('old helper');
`, `,
}, {}); }, {});
await testProcess.waitForOutput('a.test.ts:5:11 passes'); await testProcess.waitForOutput('a.test.ts:3:11 passes');
await testProcess.waitForOutput('b.test.ts:6:11 passes'); await testProcess.waitForOutput('b.test.ts:4:11 passes');
await testProcess.waitForOutput('old helper'); await testProcess.waitForOutput('old helper');
await testProcess.waitForOutput('Waiting for file changes.'); await testProcess.waitForOutput('Waiting for file changes.');
testProcess.clearOutput(); testProcess.clearOutput();
@ -343,8 +369,8 @@ test('should run on changed deps', async ({ runWatchTest, writeFiles }) => {
console.log('new helper'); console.log('new helper');
`, `,
}); });
await testProcess.waitForOutput('b.test.ts:6:11 passes'); await testProcess.waitForOutput('b.test.ts:4:11 passes');
expect(testProcess.output).not.toContain('a.test.ts:5:11 passes'); expect(testProcess.output).not.toContain('a.test.ts:3:11 passes');
await testProcess.waitForOutput('new helper'); await testProcess.waitForOutput('new helper');
await testProcess.waitForOutput('Waiting for file changes.'); await testProcess.waitForOutput('Waiting for file changes.');
}); });
@ -355,18 +381,20 @@ test('should run on changed deps in ESM', async ({ runWatchTest, writeFiles, nod
'playwright.config.ts': `export default {};`, 'playwright.config.ts': `export default {};`,
'package.json': `{ "type": "module" }`, 'package.json': `{ "type": "module" }`,
'a.test.ts': ` 'a.test.ts': `
pwt.test('passes', () => {}); import { test } from '@playwright/test';
test('passes', () => {});
`, `,
'b.test.ts': ` 'b.test.ts': `
import './helper.js'; import './helper.js';
pwt.test('passes', () => {}); import { test } from '@playwright/test';
test('passes', () => {});
`, `,
'helper.ts': ` 'helper.ts': `
console.log('old helper'); console.log('old helper');
`, `,
}, {}); }, {});
await testProcess.waitForOutput('a.test.ts:5:11 passes'); await testProcess.waitForOutput('a.test.ts:3:7 passes');
await testProcess.waitForOutput('b.test.ts:6:11 passes'); await testProcess.waitForOutput('b.test.ts:4:7 passes');
await testProcess.waitForOutput('old helper'); await testProcess.waitForOutput('old helper');
await testProcess.waitForOutput('Waiting for file changes.'); await testProcess.waitForOutput('Waiting for file changes.');
testProcess.clearOutput(); testProcess.clearOutput();
@ -375,8 +403,8 @@ test('should run on changed deps in ESM', async ({ runWatchTest, writeFiles, nod
console.log('new helper'); console.log('new helper');
`, `,
}); });
await testProcess.waitForOutput('b.test.ts:6:11 passes'); await testProcess.waitForOutput('b.test.ts:4:7 passes');
expect(testProcess.output).not.toContain('a.test.ts:5:11 passes'); expect(testProcess.output).not.toContain('a.test.ts:3:7 passes');
await testProcess.waitForOutput('new helper'); await testProcess.waitForOutput('new helper');
await testProcess.waitForOutput('Waiting for file changes.'); await testProcess.waitForOutput('Waiting for file changes.');
}); });
@ -384,49 +412,55 @@ test('should run on changed deps in ESM', async ({ runWatchTest, writeFiles, nod
test('should re-run changed files on R', async ({ runWatchTest, writeFiles }) => { test('should re-run changed files on R', async ({ runWatchTest, writeFiles }) => {
const testProcess = await runWatchTest({ const testProcess = await runWatchTest({
'a.test.ts': ` 'a.test.ts': `
pwt.test('passes', () => {}); import { test, expect } from '@playwright/test';
test('passes', () => {});
`, `,
'b.test.ts': ` 'b.test.ts': `
pwt.test('passes', () => {}); import { test, expect } from '@playwright/test';
test('passes', () => {});
`, `,
'c.test.ts': ` 'c.test.ts': `
pwt.test('fails', () => { expect(1).toBe(2); }); import { test, expect } from '@playwright/test';
test('fails', () => { expect(1).toBe(2); });
`, `,
}, {}); }, {});
await testProcess.waitForOutput('a.test.ts:5:11 passes'); await testProcess.waitForOutput('a.test.ts:3:11 passes');
await testProcess.waitForOutput('b.test.ts:5:11 passes'); await testProcess.waitForOutput('b.test.ts:3:11 passes');
await testProcess.waitForOutput('c.test.ts:5:11 fails'); await testProcess.waitForOutput('c.test.ts:3:11 fails');
await testProcess.waitForOutput('Error: expect(received).toBe(expected)'); await testProcess.waitForOutput('Error: expect(received).toBe(expected)');
await testProcess.waitForOutput('Waiting for file changes.'); await testProcess.waitForOutput('Waiting for file changes.');
testProcess.clearOutput(); testProcess.clearOutput();
await writeFiles({ await writeFiles({
'c.test.ts': ` 'c.test.ts': `
pwt.test('passes', () => {}); import { test, expect } from '@playwright/test';
test('passes', () => {});
`, `,
}); });
await testProcess.waitForOutput('c.test.ts:5:11 passes'); await testProcess.waitForOutput('c.test.ts:3:11 passes');
expect(testProcess.output).not.toContain('a.test.ts:5:11 passes'); expect(testProcess.output).not.toContain('a.test.ts:3:11 passes');
expect(testProcess.output).not.toContain('b.test.ts:5:11 passes'); expect(testProcess.output).not.toContain('b.test.ts:3:11 passes');
await testProcess.waitForOutput('Waiting for file changes.'); await testProcess.waitForOutput('Waiting for file changes.');
testProcess.clearOutput(); testProcess.clearOutput();
testProcess.write('r'); testProcess.write('r');
await testProcess.waitForOutput('c.test.ts:5:11 passes'); await testProcess.waitForOutput('c.test.ts:3:11 passes');
expect(testProcess.output).not.toContain('a.test.ts:5:11 passes'); expect(testProcess.output).not.toContain('a.test.ts:3:11 passes');
expect(testProcess.output).not.toContain('b.test.ts:5:11 passes'); expect(testProcess.output).not.toContain('b.test.ts:3:11 passes');
await testProcess.waitForOutput('Waiting for file changes.'); await testProcess.waitForOutput('Waiting for file changes.');
}); });
test('should not trigger on changes to non-tests', async ({ runWatchTest, writeFiles }) => { test('should not trigger on changes to non-tests', async ({ runWatchTest, writeFiles }) => {
const testProcess = await runWatchTest({ const testProcess = await runWatchTest({
'a.test.ts': ` 'a.test.ts': `
pwt.test('passes', () => {}); import { test, expect } from '@playwright/test';
test('passes', () => {});
`, `,
'b.test.ts': ` 'b.test.ts': `
pwt.test('passes', () => {}); import { test, expect } from '@playwright/test';
test('passes', () => {});
`, `,
}, {}); }, {});
await testProcess.waitForOutput('a.test.ts:5:11 passes'); await testProcess.waitForOutput('a.test.ts:3:11 passes');
await testProcess.waitForOutput('b.test.ts:5:11 passes'); await testProcess.waitForOutput('b.test.ts:3:11 passes');
await testProcess.waitForOutput('Waiting for file changes.'); await testProcess.waitForOutput('Waiting for file changes.');
testProcess.clearOutput(); testProcess.clearOutput();
@ -447,23 +481,25 @@ test('should only watch selected projects', async ({ runWatchTest, writeFiles })
export default defineConfig({ projects: [{name: 'foo'}, {name: 'bar'}] }); export default defineConfig({ projects: [{name: 'foo'}, {name: 'bar'}] });
`, `,
'a.test.ts': ` 'a.test.ts': `
pwt.test('passes', () => {}); import { test, expect } from '@playwright/test';
test('passes', () => {});
`, `,
}, {}, { additionalArgs: ['--project=foo'] }); }, {}, { additionalArgs: ['--project=foo'] });
await testProcess.waitForOutput('npx playwright test --project foo'); await testProcess.waitForOutput('npx playwright test --project foo');
await testProcess.waitForOutput('[foo] a.test.ts:5:11 passes'); await testProcess.waitForOutput('[foo] a.test.ts:3:11 passes');
expect(testProcess.output).not.toContain('[bar]'); expect(testProcess.output).not.toContain('[bar]');
await testProcess.waitForOutput('Waiting for file changes.'); await testProcess.waitForOutput('Waiting for file changes.');
testProcess.clearOutput(); testProcess.clearOutput();
await writeFiles({ await writeFiles({
'a.test.ts': ` 'a.test.ts': `
pwt.test('passes', () => {}); import { test, expect } from '@playwright/test';
test('passes', () => {});
`, `,
}); });
await testProcess.waitForOutput('npx playwright test --project foo'); await testProcess.waitForOutput('npx playwright test --project foo');
await testProcess.waitForOutput('[foo] a.test.ts:5:11 passes'); await testProcess.waitForOutput('[foo] a.test.ts:3:11 passes');
await testProcess.waitForOutput('Waiting for file changes.'); await testProcess.waitForOutput('Waiting for file changes.');
expect(testProcess.output).not.toContain('[bar]'); expect(testProcess.output).not.toContain('[bar]');
}); });
@ -471,21 +507,24 @@ test('should only watch selected projects', async ({ runWatchTest, writeFiles })
test('should watch filtered files', async ({ runWatchTest, writeFiles }) => { test('should watch filtered files', async ({ runWatchTest, writeFiles }) => {
const testProcess = await runWatchTest({ const testProcess = await runWatchTest({
'a.test.ts': ` 'a.test.ts': `
pwt.test('passes', () => {}); import { test, expect } from '@playwright/test';
test('passes', () => {});
`, `,
'b.test.ts': ` 'b.test.ts': `
pwt.test('passes', () => {}); import { test, expect } from '@playwright/test';
test('passes', () => {});
`, `,
}, {}, { additionalArgs: ['a.test.ts'] }); }, {}, { additionalArgs: ['a.test.ts'] });
await testProcess.waitForOutput('npx playwright test a.test.ts'); await testProcess.waitForOutput('npx playwright test a.test.ts');
await testProcess.waitForOutput('a.test.ts:5:11 passes'); await testProcess.waitForOutput('a.test.ts:3:11 passes');
expect(testProcess.output).not.toContain('b.test'); expect(testProcess.output).not.toContain('b.test');
await testProcess.waitForOutput('Waiting for file changes.'); await testProcess.waitForOutput('Waiting for file changes.');
testProcess.clearOutput(); testProcess.clearOutput();
await writeFiles({ await writeFiles({
'b.test.ts': ` 'b.test.ts': `
pwt.test('passes', () => {}); import { test, expect } from '@playwright/test';
test('passes', () => {});
`, `,
}); });
@ -496,27 +535,30 @@ test('should watch filtered files', async ({ runWatchTest, writeFiles }) => {
test('should not watch unfiltered files', async ({ runWatchTest, writeFiles }) => { test('should not watch unfiltered files', async ({ runWatchTest, writeFiles }) => {
const testProcess = await runWatchTest({ const testProcess = await runWatchTest({
'a.test.ts': ` 'a.test.ts': `
pwt.test('passes', () => {}); import { test, expect } from '@playwright/test';
test('passes', () => {});
`, `,
'b.test.ts': ` 'b.test.ts': `
pwt.test('passes', () => {}); import { test, expect } from '@playwright/test';
test('passes', () => {});
`, `,
}, {}, { additionalArgs: ['a.test.ts'] }); }, {}, { additionalArgs: ['a.test.ts'] });
await testProcess.waitForOutput('npx playwright test a.test.ts'); await testProcess.waitForOutput('npx playwright test a.test.ts');
await testProcess.waitForOutput('a.test.ts:5:11 passes'); await testProcess.waitForOutput('a.test.ts:3:11 passes');
expect(testProcess.output).not.toContain('b.test'); expect(testProcess.output).not.toContain('b.test');
await testProcess.waitForOutput('Waiting for file changes.'); await testProcess.waitForOutput('Waiting for file changes.');
testProcess.clearOutput(); testProcess.clearOutput();
await writeFiles({ await writeFiles({
'a.test.ts': ` 'a.test.ts': `
pwt.test('passes', () => {}); import { test, expect } from '@playwright/test';
test('passes', () => {});
`, `,
}); });
testProcess.clearOutput(); testProcess.clearOutput();
await testProcess.waitForOutput('npx playwright test a.test.ts (files changed)'); await testProcess.waitForOutput('npx playwright test a.test.ts (files changed)');
await testProcess.waitForOutput('a.test.ts:5:11 passes'); await testProcess.waitForOutput('a.test.ts:3:11 passes');
expect(testProcess.output).not.toContain('b.test'); expect(testProcess.output).not.toContain('b.test');
await testProcess.waitForOutput('Waiting for file changes.'); await testProcess.waitForOutput('Waiting for file changes.');
}); });
@ -533,7 +575,6 @@ test('should run CT on changed deps', async ({ runWatchTest, writeFiles }) => {
export const Button = () => <button>Button</button>; export const Button = () => <button>Button</button>;
`, `,
'src/button.spec.tsx': ` 'src/button.spec.tsx': `
//@no-header
import { test, expect } from '@playwright/experimental-ct-react'; import { test, expect } from '@playwright/experimental-ct-react';
import { Button } from './button'; import { Button } from './button';
test('pass', async ({ mount }) => { test('pass', async ({ mount }) => {
@ -542,7 +583,6 @@ test('should run CT on changed deps', async ({ runWatchTest, writeFiles }) => {
}); });
`, `,
'src/link.spec.tsx': ` 'src/link.spec.tsx': `
//@no-header
import { test, expect } from '@playwright/experimental-ct-react'; import { test, expect } from '@playwright/experimental-ct-react';
test('pass', async ({ mount }) => { test('pass', async ({ mount }) => {
const component = await mount(<a>hello</a>); const component = await mount(<a>hello</a>);
@ -550,8 +590,8 @@ test('should run CT on changed deps', async ({ runWatchTest, writeFiles }) => {
}); });
`, `,
}, {}); }, {});
await testProcess.waitForOutput('button.spec.tsx:5:11 pass'); await testProcess.waitForOutput('button.spec.tsx:4:11 pass');
await testProcess.waitForOutput('link.spec.tsx:4:11 pass'); await testProcess.waitForOutput('link.spec.tsx:3:11 pass');
await testProcess.waitForOutput('Waiting for file changes.'); await testProcess.waitForOutput('Waiting for file changes.');
testProcess.clearOutput(); testProcess.clearOutput();
await writeFiles({ await writeFiles({
@ -560,7 +600,7 @@ test('should run CT on changed deps', async ({ runWatchTest, writeFiles }) => {
`, `,
}); });
await testProcess.waitForOutput(`src${path.sep}button.spec.tsx:5:11 pass`); await testProcess.waitForOutput(`src${path.sep}button.spec.tsx:4:11 pass`);
expect(testProcess.output).not.toContain(`src${path.sep}link.spec.tsx`); expect(testProcess.output).not.toContain(`src${path.sep}link.spec.tsx`);
await testProcess.waitForOutput('Error: expect(received).toHaveText(expected)'); await testProcess.waitForOutput('Error: expect(received).toHaveText(expected)');
await testProcess.waitForOutput('Waiting for file changes.'); await testProcess.waitForOutput('Waiting for file changes.');
@ -582,7 +622,6 @@ test('should run CT on indirect deps change', async ({ runWatchTest, writeFiles
export const Button = () => <button>Button</button>; export const Button = () => <button>Button</button>;
`, `,
'src/button.spec.tsx': ` 'src/button.spec.tsx': `
//@no-header
import { test, expect } from '@playwright/experimental-ct-react'; import { test, expect } from '@playwright/experimental-ct-react';
import { Button } from './button'; import { Button } from './button';
test('pass', async ({ mount }) => { test('pass', async ({ mount }) => {
@ -591,7 +630,6 @@ test('should run CT on indirect deps change', async ({ runWatchTest, writeFiles
}); });
`, `,
'src/link.spec.tsx': ` 'src/link.spec.tsx': `
//@no-header
import { test, expect } from '@playwright/experimental-ct-react'; import { test, expect } from '@playwright/experimental-ct-react';
test('pass', async ({ mount }) => { test('pass', async ({ mount }) => {
const component = await mount(<a>hello</a>); const component = await mount(<a>hello</a>);
@ -599,8 +637,8 @@ test('should run CT on indirect deps change', async ({ runWatchTest, writeFiles
}); });
`, `,
}, {}); }, {});
await testProcess.waitForOutput('button.spec.tsx:5:11 pass'); await testProcess.waitForOutput('button.spec.tsx:4:11 pass');
await testProcess.waitForOutput('link.spec.tsx:4:11 pass'); await testProcess.waitForOutput('link.spec.tsx:3:11 pass');
await testProcess.waitForOutput('Waiting for file changes.'); await testProcess.waitForOutput('Waiting for file changes.');
testProcess.clearOutput(); testProcess.clearOutput();
await writeFiles({ await writeFiles({
@ -609,7 +647,7 @@ test('should run CT on indirect deps change', async ({ runWatchTest, writeFiles
`, `,
}); });
await testProcess.waitForOutput(`src${path.sep}button.spec.tsx:5:11 pass`); await testProcess.waitForOutput(`src${path.sep}button.spec.tsx:4:11 pass`);
expect(testProcess.output).not.toContain(`src${path.sep}link.spec.tsx`); expect(testProcess.output).not.toContain(`src${path.sep}link.spec.tsx`);
await testProcess.waitForOutput('Waiting for file changes.'); await testProcess.waitForOutput('Waiting for file changes.');
}); });
@ -632,7 +670,6 @@ test('should run CT on indirect deps change ESM mode', async ({ runWatchTest, wr
export const Button = () => <button>Button</button>; export const Button = () => <button>Button</button>;
`, `,
'src/button.spec.tsx': ` 'src/button.spec.tsx': `
//@no-header
import { test, expect } from '@playwright/experimental-ct-react'; import { test, expect } from '@playwright/experimental-ct-react';
import { Button } from './button.jsx'; import { Button } from './button.jsx';
test('pass', async ({ mount }) => { test('pass', async ({ mount }) => {
@ -641,7 +678,6 @@ test('should run CT on indirect deps change ESM mode', async ({ runWatchTest, wr
}); });
`, `,
'src/link.spec.tsx': ` 'src/link.spec.tsx': `
//@no-header
import { test, expect } from '@playwright/experimental-ct-react'; import { test, expect } from '@playwright/experimental-ct-react';
test('pass', async ({ mount }) => { test('pass', async ({ mount }) => {
const component = await mount(<a>hello</a>); const component = await mount(<a>hello</a>);
@ -649,8 +685,8 @@ test('should run CT on indirect deps change ESM mode', async ({ runWatchTest, wr
}); });
`, `,
}, {}); }, {});
await testProcess.waitForOutput('button.spec.tsx:5:7 pass'); await testProcess.waitForOutput('button.spec.tsx:4:7 pass');
await testProcess.waitForOutput('link.spec.tsx:4:7 pass'); await testProcess.waitForOutput('link.spec.tsx:3:7 pass');
await testProcess.waitForOutput('Waiting for file changes.'); await testProcess.waitForOutput('Waiting for file changes.');
testProcess.clearOutput(); testProcess.clearOutput();
await writeFiles({ await writeFiles({
@ -659,7 +695,7 @@ test('should run CT on indirect deps change ESM mode', async ({ runWatchTest, wr
`, `,
}); });
await testProcess.waitForOutput(`src${path.sep}button.spec.tsx:5:7 pass`); await testProcess.waitForOutput(`src${path.sep}button.spec.tsx:4:7 pass`);
expect(testProcess.output).not.toContain(`src${path.sep}link.spec.tsx`); expect(testProcess.output).not.toContain(`src${path.sep}link.spec.tsx`);
await testProcess.waitForOutput('Waiting for file changes.'); await testProcess.waitForOutput('Waiting for file changes.');
}); });

View File

@ -24,7 +24,7 @@ test('should create a server', async ({ runInlineTest }, { workerIndex }) => {
const port = workerIndex * 2 + 10500; const port = workerIndex * 2 + 10500;
const result = await runInlineTest({ const result = await runInlineTest({
'test.spec.ts': ` 'test.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('connect to the server via the baseURL', async ({baseURL, page}) => { test('connect to the server via the baseURL', async ({baseURL, page}) => {
await page.goto('/hello'); await page.goto('/hello');
await page.waitForURL('/hello'); await page.waitForURL('/hello');
@ -43,7 +43,7 @@ test('should create a server', async ({ runInlineTest }, { workerIndex }) => {
}; };
`, `,
'globalSetup.ts': ` 'globalSetup.ts': `
const { expect } = pwt; import { expect } from '@playwright/test';
module.exports = async (config) => { module.exports = async (config) => {
expect(config.webServer.port, "For backwards compatibility reasons, we ensure this shows up.").toBe(${port}); expect(config.webServer.port, "For backwards compatibility reasons, we ensure this shows up.").toBe(${port});
const http = require("http"); const http = require("http");
@ -90,7 +90,7 @@ test('should create a server with environment variables', async ({ runInlineTest
const port = workerIndex * 2 + 10500; const port = workerIndex * 2 + 10500;
const result = await runInlineTest({ const result = await runInlineTest({
'test.spec.ts': ` 'test.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('connect to the server', async ({baseURL, page}) => { test('connect to the server', async ({baseURL, page}) => {
expect(baseURL).toBe('http://localhost:${port}'); expect(baseURL).toBe('http://localhost:${port}');
await page.goto(baseURL + '/env-FOO'); await page.goto(baseURL + '/env-FOO');
@ -122,7 +122,7 @@ test('should default cwd to config directory', async ({ runInlineTest }, testInf
const relativeSimpleServerPath = path.relative(configDir, SIMPLE_SERVER_PATH); const relativeSimpleServerPath = path.relative(configDir, SIMPLE_SERVER_PATH);
const result = await runInlineTest({ const result = await runInlineTest({
'foo/test.spec.ts': ` 'foo/test.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('connect to the server', async ({ baseURL }) => { test('connect to the server', async ({ baseURL }) => {
expect(baseURL).toBe('http://localhost:${port}'); expect(baseURL).toBe('http://localhost:${port}');
}); });
@ -150,7 +150,7 @@ test('should resolve cwd wrt config directory', async ({ runInlineTest }, testIn
const relativeSimpleServerPath = path.relative(testdir, SIMPLE_SERVER_PATH); const relativeSimpleServerPath = path.relative(testdir, SIMPLE_SERVER_PATH);
const result = await runInlineTest({ const result = await runInlineTest({
'foo/test.spec.ts': ` 'foo/test.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('connect to the server', async ({ baseURL }) => { test('connect to the server', async ({ baseURL }) => {
expect(baseURL).toBe('http://localhost:${port}'); expect(baseURL).toBe('http://localhost:${port}');
}); });
@ -178,7 +178,7 @@ test('should create a server with url', async ({ runInlineTest }, { workerIndex
const port = workerIndex * 2 + 10500; const port = workerIndex * 2 + 10500;
const result = await runInlineTest({ const result = await runInlineTest({
'test.spec.ts': ` 'test.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('connect to the server', async ({baseURL, page}) => { test('connect to the server', async ({baseURL, page}) => {
expect(baseURL).toBe(undefined); expect(baseURL).toBe(undefined);
await page.goto('http://localhost:${port}/ready'); await page.goto('http://localhost:${port}/ready');
@ -203,7 +203,7 @@ test('should time out waiting for a server', async ({ runInlineTest }, { workerI
const port = workerIndex * 2 + 10500; const port = workerIndex * 2 + 10500;
const result = await runInlineTest({ const result = await runInlineTest({
'test.spec.ts': ` 'test.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('connect to the server', async ({baseURL, page}) => { test('connect to the server', async ({baseURL, page}) => {
expect(baseURL).toBe('http://localhost:${port}'); expect(baseURL).toBe('http://localhost:${port}');
await page.goto(baseURL + '/hello'); await page.goto(baseURL + '/hello');
@ -228,7 +228,7 @@ test('should time out waiting for a server with url', async ({ runInlineTest },
const port = workerIndex * 2 + 10500; const port = workerIndex * 2 + 10500;
const result = await runInlineTest({ const result = await runInlineTest({
'test.spec.ts': ` 'test.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('connect to the server', async ({baseURL, page}) => { test('connect to the server', async ({baseURL, page}) => {
expect(baseURL).toBe('http://localhost:${port}/ready'); expect(baseURL).toBe('http://localhost:${port}/ready');
await page.goto(baseURL); await page.goto(baseURL);
@ -257,7 +257,7 @@ test('should be able to specify the baseURL without the server', async ({ runInl
await new Promise<void>(resolve => server.listen(port, resolve)); await new Promise<void>(resolve => server.listen(port, resolve));
const result = await runInlineTest({ const result = await runInlineTest({
'test.spec.ts': ` 'test.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('connect to the server', async ({baseURL, page}) => { test('connect to the server', async ({baseURL, page}) => {
expect(baseURL).toBe('http://localhost:${port}'); expect(baseURL).toBe('http://localhost:${port}');
await page.goto(baseURL + '/hello'); await page.goto(baseURL + '/hello');
@ -287,7 +287,7 @@ test('should be able to specify a custom baseURL with the server', async ({ runI
await new Promise<void>(resolve => server.listen(customWebServerPort, resolve)); await new Promise<void>(resolve => server.listen(customWebServerPort, resolve));
const result = await runInlineTest({ const result = await runInlineTest({
'test.spec.ts': ` 'test.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('connect to the server', async ({baseURL, page}) => { test('connect to the server', async ({baseURL, page}) => {
expect(baseURL).toBe('http://localhost:${customWebServerPort}'); expect(baseURL).toBe('http://localhost:${customWebServerPort}');
await page.goto(baseURL + '/hello'); await page.goto(baseURL + '/hello');
@ -320,7 +320,7 @@ test('should be able to use an existing server when reuseExistingServer:true', a
await new Promise<void>(resolve => server.listen(port, resolve)); await new Promise<void>(resolve => server.listen(port, resolve));
const result = await runInlineTest({ const result = await runInlineTest({
'test.spec.ts': ` 'test.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('connect to the server via the baseURL', async ({baseURL, page}) => { test('connect to the server via the baseURL', async ({baseURL, page}) => {
await page.goto('/hello'); await page.goto('/hello');
await page.waitForURL('/hello'); await page.waitForURL('/hello');
@ -353,7 +353,7 @@ test('should throw when a server is already running on the given port and strict
await new Promise<void>(resolve => server.listen(port, resolve)); await new Promise<void>(resolve => server.listen(port, resolve));
const result = await runInlineTest({ const result = await runInlineTest({
'test.spec.ts': ` 'test.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('connect to the server via the baseURL', async ({baseURL, page}) => { test('connect to the server via the baseURL', async ({baseURL, page}) => {
await page.goto('/hello'); await page.goto('/hello');
await page.waitForURL('/hello'); await page.waitForURL('/hello');
@ -386,7 +386,7 @@ for (const host of ['localhost', '127.0.0.1', '0.0.0.0']) {
try { try {
const result = await runInlineTest({ const result = await runInlineTest({
'test.spec.ts': ` 'test.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('connect to the server via the baseURL', async ({baseURL, page}) => { test('connect to the server via the baseURL', async ({baseURL, page}) => {
await page.goto('/hello'); await page.goto('/hello');
expect(await page.textContent('body')).toBe('hello'); expect(await page.textContent('body')).toBe('hello');
@ -413,7 +413,7 @@ for (const host of ['localhost', '127.0.0.1', '0.0.0.0']) {
test(`should support self signed certificate`, async ({ runInlineTest, httpsServer }) => { test(`should support self signed certificate`, async ({ runInlineTest, httpsServer }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'test.spec.js': ` 'test.spec.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async ({}) => { }); test('pass', async ({}) => { });
`, `,
'playwright.config.js': ` 'playwright.config.js': `
@ -437,7 +437,7 @@ test('should send Accept header', async ({ runInlineTest, server }) => {
}); });
const result = await runInlineTest({ const result = await runInlineTest({
'test.spec.ts': ` 'test.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('connect to the server', async ({baseURL, page}) => { test('connect to the server', async ({baseURL, page}) => {
await page.goto('http://localhost:${server.PORT}/hello'); await page.goto('http://localhost:${server.PORT}/hello');
expect(await page.textContent('body')).toBe('hello'); expect(await page.textContent('body')).toBe('hello');
@ -461,7 +461,7 @@ test('should create multiple servers', async ({ runInlineTest }, { workerIndex }
const port = workerIndex * 2 + 10500; const port = workerIndex * 2 + 10500;
const result = await runInlineTest({ const result = await runInlineTest({
'test.spec.ts': ` 'test.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('connect to the server', async ({page}) => { test('connect to the server', async ({page}) => {
await page.goto('http://localhost:${port}/port'); await page.goto('http://localhost:${port}/port');
@ -488,7 +488,7 @@ test('should create multiple servers', async ({ runInlineTest }, { workerIndex }
}; };
`, `,
'globalSetup.ts': ` 'globalSetup.ts': `
const { expect } = pwt; import { expect } from '@playwright/test';
module.exports = async (config) => { module.exports = async (config) => {
expect(config.webServer, "The public API defines this type as singleton or null, so if using array style we fallback to null to avoid having the type lie to the user.").toBe(null); expect(config.webServer, "The public API defines this type as singleton or null, so if using array style we fallback to null to avoid having the type lie to the user.").toBe(null);
const http = require("http"); const http = require("http");
@ -536,7 +536,7 @@ test.describe('baseURL with plugins', () => {
const port = workerIndex * 2 + 10500; const port = workerIndex * 2 + 10500;
const result = await runInlineTest({ const result = await runInlineTest({
'test.spec.ts': ` 'test.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('connect to the server', async ({baseURL, page}) => { test('connect to the server', async ({baseURL, page}) => {
expect(baseURL).toBeUndefined(); expect(baseURL).toBeUndefined();
}); });
@ -561,7 +561,7 @@ test.describe('baseURL with plugins', () => {
const port = workerIndex * 2 + 10500; const port = workerIndex * 2 + 10500;
const result = await runInlineTest({ const result = await runInlineTest({
'test.spec.ts': ` 'test.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('connect to the server', async ({baseURL, page}) => { test('connect to the server', async ({baseURL, page}) => {
expect(baseURL).toBe('http://localhost:${port}'); expect(baseURL).toBe('http://localhost:${port}');
}); });
@ -591,7 +591,7 @@ test('should treat 3XX as available server', async ({ runInlineTest }, { workerI
const port = workerIndex * 2 + 10500; const port = workerIndex * 2 + 10500;
const result = await runInlineTest({ const result = await runInlineTest({
'test.spec.ts': ` 'test.spec.ts': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('pass', async ({}) => {}); test('pass', async ({}) => {});
`, `,
'playwright.config.ts': ` 'playwright.config.ts': `

View File

@ -21,7 +21,7 @@ test('should run in parallel', async ({ runInlineTest }) => {
'1.spec.ts': ` '1.spec.ts': `
import * as fs from 'fs'; import * as fs from 'fs';
import * as path from 'path'; import * as path from 'path';
const { test } = pwt; import { test, expect } from '@playwright/test';
test('succeeds', async ({}, testInfo) => { test('succeeds', async ({}, testInfo) => {
expect(testInfo.workerIndex).toBe(0); expect(testInfo.workerIndex).toBe(0);
expect(testInfo.parallelIndex).toBe(0); expect(testInfo.parallelIndex).toBe(0);
@ -36,7 +36,7 @@ test('should run in parallel', async ({ runInlineTest }) => {
'2.spec.ts': ` '2.spec.ts': `
import * as fs from 'fs'; import * as fs from 'fs';
import * as path from 'path'; import * as path from 'path';
const { test } = pwt; import { test, expect } from '@playwright/test';
test('succeeds', async ({}, testInfo) => { test('succeeds', async ({}, testInfo) => {
// First test waits for the second to start to work around the race. // First test waits for the second to start to work around the race.
fs.mkdirSync(testInfo.project.outputDir, { recursive: true }); fs.mkdirSync(testInfo.project.outputDir, { recursive: true });
@ -53,7 +53,7 @@ test('should run in parallel', async ({ runInlineTest }) => {
test('should reuse worker for multiple tests', async ({ runInlineTest }) => { test('should reuse worker for multiple tests', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('succeeds 1', async ({}, testInfo) => { test('succeeds 1', async ({}, testInfo) => {
expect(testInfo.workerIndex).toBe(0); expect(testInfo.workerIndex).toBe(0);
expect(testInfo.parallelIndex).toBe(0); expect(testInfo.parallelIndex).toBe(0);
@ -77,7 +77,7 @@ test('should reuse worker for multiple tests', async ({ runInlineTest }) => {
test('should reuse worker after test.fixme()', async ({ runInlineTest }) => { test('should reuse worker after test.fixme()', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('succeeds 1', async ({}, testInfo) => { test('succeeds 1', async ({}, testInfo) => {
expect(testInfo.workerIndex).toBe(0); expect(testInfo.workerIndex).toBe(0);
expect(testInfo.parallelIndex).toBe(0); expect(testInfo.parallelIndex).toBe(0);
@ -103,7 +103,7 @@ test('should reuse worker after test.fixme()', async ({ runInlineTest }) => {
test('should reuse worker after test.skip()', async ({ runInlineTest }) => { test('should reuse worker after test.skip()', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('succeeds 1', async ({}, testInfo) => { test('succeeds 1', async ({}, testInfo) => {
expect(testInfo.workerIndex).toBe(0); expect(testInfo.workerIndex).toBe(0);
expect(testInfo.parallelIndex).toBe(0); expect(testInfo.parallelIndex).toBe(0);
@ -129,7 +129,7 @@ test('should reuse worker after test.skip()', async ({ runInlineTest }) => {
test('should not use new worker after test.fail()', async ({ runInlineTest }) => { test('should not use new worker after test.fail()', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('succeeds 1', async ({}, testInfo) => { test('succeeds 1', async ({}, testInfo) => {
expect(testInfo.workerIndex).toBe(0); expect(testInfo.workerIndex).toBe(0);
expect(testInfo.parallelIndex).toBe(0); expect(testInfo.parallelIndex).toBe(0);
@ -154,7 +154,7 @@ test('should not use new worker after test.fail()', async ({ runInlineTest }) =>
test('should use new worker after test failure', async ({ runInlineTest }) => { test('should use new worker after test failure', async ({ runInlineTest }) => {
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('succeeds 1', async ({}, testInfo) => { test('succeeds 1', async ({}, testInfo) => {
expect(testInfo.workerIndex).toBe(0); expect(testInfo.workerIndex).toBe(0);
expect(testInfo.parallelIndex).toBe(0); expect(testInfo.parallelIndex).toBe(0);
@ -181,7 +181,7 @@ test('should not reuse worker for different suites', async ({ runInlineTest }) =
module.exports = { projects: [{}, {}, {}] }; module.exports = { projects: [{}, {}, {}] };
`, `,
'a.test.js': ` 'a.test.js': `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('succeeds', async ({}, testInfo) => { test('succeeds', async ({}, testInfo) => {
console.log('workerIndex-' + testInfo.workerIndex); console.log('workerIndex-' + testInfo.workerIndex);
console.log('parallelIndex-' + testInfo.parallelIndex); console.log('parallelIndex-' + testInfo.parallelIndex);
@ -202,7 +202,7 @@ test('parallelIndex should be in 0..workers-1', async ({ runInlineTest }) => {
const files = {}; const files = {};
for (let i = 0; i < 10; i++) { for (let i = 0; i < 10; i++) {
files[`a${i}.test.js`] = ` files[`a${i}.test.js`] = `
const { test } = pwt; import { test, expect } from '@playwright/test';
test('passes-1', async ({}, testInfo) => { test('passes-1', async ({}, testInfo) => {
await new Promise(f => setTimeout(f, 100 + 50 * ${i})); await new Promise(f => setTimeout(f, 100 + 50 * ${i}));
expect(testInfo.parallelIndex >= 0).toBeTruthy(); expect(testInfo.parallelIndex >= 0).toBeTruthy();
@ -226,7 +226,7 @@ test('should not spawn workers for statically skipped tests', async ({ runInline
const result = await runInlineTest({ const result = await runInlineTest({
'a.test.js': ` 'a.test.js': `
console.log('%%workerIndex=' + process.env.TEST_WORKER_INDEX); console.log('%%workerIndex=' + process.env.TEST_WORKER_INDEX);
const { test } = pwt; import { test, expect } from '@playwright/test';
test.describe.configure({ mode: 'parallel' }); test.describe.configure({ mode: 'parallel' });
test('success', () => {}); test('success', () => {});
test.skip('skipped', () => {}); test.skip('skipped', () => {});