197 lines
6.3 KiB
TypeScript
197 lines
6.3 KiB
TypeScript
|
|
/**
|
||
|
|
* Copyright (c) Microsoft Corporation.
|
||
|
|
*
|
||
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
|
* you may not use this file except in compliance with the License.
|
||
|
|
* You may obtain a copy of the License at
|
||
|
|
*
|
||
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||
|
|
*
|
||
|
|
* Unless required by applicable law or agreed to in writing, software
|
||
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
|
* See the License for the specific language governing permissions and
|
||
|
|
* limitations under the License.
|
||
|
|
*/
|
||
|
|
|
||
|
|
import { TestCase, TestResult, TestStep } from '../../packages/playwright-test/reporter';
|
||
|
|
import { ReporterV2 } from '../../packages/playwright/src/reporters/reporterV2';
|
||
|
|
import { test, expect } from './playwright-test-fixtures';
|
||
|
|
|
||
|
|
test.describe.configure({ mode: 'parallel' });
|
||
|
|
|
||
|
|
class LocationReporter implements ReporterV2 {
|
||
|
|
private _foundErrors = 0;
|
||
|
|
version() {
|
||
|
|
return 'v2' as const;
|
||
|
|
}
|
||
|
|
onStepBegin(test: TestCase, result: TestResult, step: TestStep): void {
|
||
|
|
if (step.title === 'Paused') {
|
||
|
|
console.log(`%%onStepBegin: ${step.titlePath().join(' > ')} at :${step.location?.line}:${step.location?.column}`);
|
||
|
|
this._printErrors(result);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
async onTestPaused(test: TestCase, result: TestResult) {
|
||
|
|
if (result.error)
|
||
|
|
console.log(`%%onTestPaused on error at :${result.error.location?.line}:${result.error.location?.column}`);
|
||
|
|
else
|
||
|
|
console.log(`%%onTestPaused at end`);
|
||
|
|
this._printErrors(result);
|
||
|
|
if (process.env.SIGINT_AFTER_PAUSE) {
|
||
|
|
console.log('%%SIGINT');
|
||
|
|
process.kill(process.pid, 'SIGINT');
|
||
|
|
await new Promise(() => {});
|
||
|
|
}
|
||
|
|
}
|
||
|
|
onStepEnd(test: TestCase, result: TestResult, step: TestStep): void {
|
||
|
|
if (step.title === 'Paused') {
|
||
|
|
console.log(`%%onStepEnd: ${step.titlePath().join(' > ')}`);
|
||
|
|
this._printErrors(result);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
onTestEnd(test: TestCase, result: TestResult): void {
|
||
|
|
console.log('%%onTestEnd');
|
||
|
|
this._printErrors(result);
|
||
|
|
}
|
||
|
|
onStdOut(chunk: string | Buffer) {
|
||
|
|
console.log(chunk);
|
||
|
|
}
|
||
|
|
private _printErrors(result: TestResult) {
|
||
|
|
for (const [index, error] of result.errors.entries()) {
|
||
|
|
if (index >= this._foundErrors)
|
||
|
|
console.log(`%%result.errors[${index}] at :${error.location?.line}:${error.location?.column}`);
|
||
|
|
}
|
||
|
|
this._foundErrors = result.errors.length;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
test('--pause should pause at end', async ({ runInlineTest }) => {
|
||
|
|
const result = await runInlineTest({
|
||
|
|
'location-reporter.js': `export default ${LocationReporter}`,
|
||
|
|
'playwright.config.js': `
|
||
|
|
module.exports = { reporter: './location-reporter.js' };
|
||
|
|
`,
|
||
|
|
'a.test.js': `
|
||
|
|
import { test, expect } from '@playwright/test';
|
||
|
|
test('pass', () => {
|
||
|
|
});
|
||
|
|
test.afterEach(() => {
|
||
|
|
console.log('%%teardown');
|
||
|
|
});
|
||
|
|
`
|
||
|
|
}, {}, { PWPAUSE: '1' });
|
||
|
|
expect(result.outputLines).toEqual([
|
||
|
|
'onTestPaused at end',
|
||
|
|
'teardown',
|
||
|
|
'onTestEnd',
|
||
|
|
]);
|
||
|
|
});
|
||
|
|
|
||
|
|
test('--pause should pause at end with setup project', async ({ runInlineTest }) => {
|
||
|
|
const result = await runInlineTest({
|
||
|
|
'location-reporter.js': `export default ${LocationReporter}`,
|
||
|
|
'playwright.config.js': `
|
||
|
|
module.exports = {
|
||
|
|
reporter: './location-reporter.js',
|
||
|
|
projects: [
|
||
|
|
{ name: 'setup', testMatch: /setup\\.test\\.js/ },
|
||
|
|
{ name: 'main', dependencies: ['setup'] }
|
||
|
|
]
|
||
|
|
};
|
||
|
|
`,
|
||
|
|
'setup.test.js': `
|
||
|
|
import { test } from '@playwright/test';
|
||
|
|
test('setup', () => {
|
||
|
|
});
|
||
|
|
`,
|
||
|
|
'a.test.js': `
|
||
|
|
import { test, expect } from '@playwright/test';
|
||
|
|
test('pass', () => {
|
||
|
|
console.log('main test started');
|
||
|
|
});
|
||
|
|
`
|
||
|
|
}, {}, { PWPAUSE: '1' });
|
||
|
|
expect(result.outputLines).toContain('onTestPaused at end');
|
||
|
|
});
|
||
|
|
|
||
|
|
test('--pause should pause on error', async ({ runInlineTest, mergeReports }) => {
|
||
|
|
const result = await runInlineTest({
|
||
|
|
'location-reporter.js': `export default ${LocationReporter}`,
|
||
|
|
'playwright.config.js': `
|
||
|
|
module.exports = { reporter: [['./location-reporter.js'], ['blob']] };
|
||
|
|
`,
|
||
|
|
'a.test.js': `
|
||
|
|
import { test, expect } from '@playwright/test';
|
||
|
|
test('pass', () => {
|
||
|
|
expect.soft(1).toBe(2);
|
||
|
|
expect(2).toBe(3);
|
||
|
|
console.log('%%after error');
|
||
|
|
});
|
||
|
|
`
|
||
|
|
}, {}, { PWPAUSE: '1' });
|
||
|
|
expect(result.outputLines).toEqual([
|
||
|
|
'onTestPaused on error at :4:24',
|
||
|
|
'result.errors[0] at :4:24',
|
||
|
|
'result.errors[1] at :5:19',
|
||
|
|
'onTestEnd',
|
||
|
|
]);
|
||
|
|
|
||
|
|
const merged = await mergeReports('blob-report', undefined, { additionalArgs: ['--reporter', 'location-reporter.js'] });
|
||
|
|
expect(merged.outputLines, 'merge reporter doesnt get onTestPaused').toEqual([
|
||
|
|
'onTestEnd',
|
||
|
|
'result.errors[0] at :4:24',
|
||
|
|
'result.errors[1] at :5:19',
|
||
|
|
]);
|
||
|
|
});
|
||
|
|
|
||
|
|
test('SIGINT after pause at end should still run teardown', async ({ runInlineTest }) => {
|
||
|
|
test.skip(process.platform === 'win32', 'no SIGINT on windows');
|
||
|
|
const result = await runInlineTest({
|
||
|
|
'location-reporter.js': `export default ${LocationReporter}`,
|
||
|
|
'playwright.config.js': `
|
||
|
|
module.exports = { reporter: './location-reporter.js' };
|
||
|
|
`,
|
||
|
|
'a.test.js': `
|
||
|
|
import { test, expect } from '@playwright/test';
|
||
|
|
test('pass', () => {
|
||
|
|
});
|
||
|
|
test.afterEach(() => {
|
||
|
|
console.log('%%teardown');
|
||
|
|
});
|
||
|
|
`
|
||
|
|
}, {}, { PWPAUSE: '1', SIGINT_AFTER_PAUSE: '1' });
|
||
|
|
expect(result.outputLines).toEqual([
|
||
|
|
'onTestPaused at end',
|
||
|
|
'SIGINT',
|
||
|
|
'teardown',
|
||
|
|
'onTestEnd',
|
||
|
|
]);
|
||
|
|
});
|
||
|
|
|
||
|
|
test('SIGINT after pause on error should still run teardown', async ({ runInlineTest }) => {
|
||
|
|
test.skip(process.platform === 'win32', 'no SIGINT on windows');
|
||
|
|
const result = await runInlineTest({
|
||
|
|
'location-reporter.js': `export default ${LocationReporter}`,
|
||
|
|
'playwright.config.js': `
|
||
|
|
module.exports = { reporter: './location-reporter.js' };
|
||
|
|
`,
|
||
|
|
'a.test.js': `
|
||
|
|
import { test, expect } from '@playwright/test';
|
||
|
|
test('pass', () => {
|
||
|
|
expect(2).toBe(3);
|
||
|
|
console.log('%%after error');
|
||
|
|
});
|
||
|
|
test.afterEach(() => {
|
||
|
|
console.log('%%teardown');
|
||
|
|
});
|
||
|
|
`
|
||
|
|
}, {}, { PWPAUSE: '1', SIGINT_AFTER_PAUSE: '1' });
|
||
|
|
expect(result.outputLines).toEqual([
|
||
|
|
'onTestPaused on error at :4:19',
|
||
|
|
'result.errors[0] at :4:19',
|
||
|
|
'SIGINT',
|
||
|
|
'teardown',
|
||
|
|
'onTestEnd',
|
||
|
|
]);
|
||
|
|
});
|