mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00
test: replace sendSIGINTAfter with interactWithTestRunner (#24411)
This way we can send multiple SIGINTs in tests.
This commit is contained in:
parent
9d0bba9c99
commit
ed14bf2103
@ -204,8 +204,8 @@ export class TestChildProcess {
|
||||
throw new Error(`Process received signal: ${r.signal}`);
|
||||
}
|
||||
|
||||
async waitForOutput(substring: string) {
|
||||
while (!stripAnsi(this.output).includes(substring))
|
||||
async waitForOutput(substring: string, count = 1) {
|
||||
while (countTimes(stripAnsi(this.output), substring) < count)
|
||||
await new Promise<void>(f => this._outputCallbacks.add(f));
|
||||
}
|
||||
|
||||
@ -275,3 +275,15 @@ export const commonFixtures: Fixtures<CommonFixtures, CommonWorkerFixtures> = {
|
||||
token.canceled = true;
|
||||
},
|
||||
};
|
||||
|
||||
export function countTimes(s: string, sub: string): number {
|
||||
let result = 0;
|
||||
for (let index = 0; index !== -1;) {
|
||||
index = s.indexOf(sub, index);
|
||||
if (index !== -1) {
|
||||
result++;
|
||||
index += sub.length;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
import path from 'path';
|
||||
import { test, expect } from './playwright-test-fixtures';
|
||||
import { test, expect, parseTestRunnerOutput } from './playwright-test-fixtures';
|
||||
|
||||
test('should be able to call expect.extend in config', async ({ runInlineTest }) => {
|
||||
const result = await runInlineTest({
|
||||
@ -588,10 +588,10 @@ test('should print pending operations for toHaveText', async ({ runInlineTest })
|
||||
expect(output).toContain('waiting for locator(\'no-such-thing\')');
|
||||
});
|
||||
|
||||
test('should print expected/received on Ctrl+C', async ({ runInlineTest }) => {
|
||||
test('should print expected/received on Ctrl+C', async ({ interactWithTestRunner }) => {
|
||||
test.skip(process.platform === 'win32', 'No sending SIGINT on Windows');
|
||||
|
||||
const result = await runInlineTest({
|
||||
const testProcess = await interactWithTestRunner({
|
||||
'a.test.ts': `
|
||||
import { test, expect } from '@playwright/test';
|
||||
|
||||
@ -603,8 +603,13 @@ test('should print expected/received on Ctrl+C', async ({ runInlineTest }) => {
|
||||
await promise;
|
||||
});
|
||||
`,
|
||||
}, { workers: 1 }, {}, { sendSIGINTAfter: 1 });
|
||||
expect(result.exitCode).toBe(130);
|
||||
}, { workers: 1 });
|
||||
await testProcess.waitForOutput('%%SEND-SIGINT%%');
|
||||
process.kill(testProcess.process.pid!, 'SIGINT');
|
||||
const { exitCode } = await testProcess.exited;
|
||||
expect(exitCode).toBe(130);
|
||||
|
||||
const result = parseTestRunnerOutput(testProcess.output);
|
||||
expect(result.passed).toBe(0);
|
||||
expect(result.interrupted).toBe(1);
|
||||
expect(result.output).toContain('Expected string: "Text 2"');
|
||||
|
||||
@ -26,8 +26,9 @@ import { serverFixtures } from '../config/serverFixtures';
|
||||
import type { TestInfo } from './stable-test-runner';
|
||||
import { expect } from './stable-test-runner';
|
||||
import { test as base } from './stable-test-runner';
|
||||
export { countTimes } from '../config/commonFixtures';
|
||||
|
||||
export type CliRunResult = {
|
||||
type CliRunResult = {
|
||||
exitCode: number,
|
||||
output: string,
|
||||
};
|
||||
@ -92,13 +93,7 @@ const configFile = (baseDir: string, files: Files): string | undefined => {
|
||||
return undefined;
|
||||
};
|
||||
|
||||
async function runPlaywrightTest(childProcess: CommonFixtures['childProcess'], baseDir: string, params: any, env: NodeJS.ProcessEnv, options: RunOptions, files: Files, mergeReports: (reportFolder: string, env?: NodeJS.ProcessEnv, options?: RunOptions) => Promise<CliRunResult>, useIntermediateMergeReport: boolean): Promise<RunResult> {
|
||||
let reporter;
|
||||
if (useIntermediateMergeReport) {
|
||||
reporter = params.reporter;
|
||||
params.reporter = 'blob';
|
||||
}
|
||||
|
||||
function startPlaywrightTest(childProcess: CommonFixtures['childProcess'], baseDir: string, params: any, env: NodeJS.ProcessEnv, options: RunOptions): TestChildProcess {
|
||||
const paramList: string[] = [];
|
||||
for (const key of Object.keys(params)) {
|
||||
for (const value of Array.isArray(params[key]) ? params[key] : [params[key]]) {
|
||||
@ -106,7 +101,6 @@ async function runPlaywrightTest(childProcess: CommonFixtures['childProcess'], b
|
||||
paramList.push(params[key] === true ? `${k}` : `${k}=${value}`);
|
||||
}
|
||||
}
|
||||
const reportFile = path.join(baseDir, 'report.json');
|
||||
const args = ['test'];
|
||||
args.push(
|
||||
'--workers=2',
|
||||
@ -114,14 +108,27 @@ async function runPlaywrightTest(childProcess: CommonFixtures['childProcess'], b
|
||||
);
|
||||
if (options.additionalArgs)
|
||||
args.push(...options.additionalArgs);
|
||||
return childProcess({
|
||||
command: ['node', cliEntrypoint, ...args],
|
||||
env: cleanEnv(env),
|
||||
cwd: options.cwd ? path.resolve(baseDir, options.cwd) : baseDir,
|
||||
});
|
||||
}
|
||||
|
||||
const cwd = options.cwd ? path.resolve(baseDir, options.cwd) : baseDir;
|
||||
// eslint-disable-next-line prefer-const
|
||||
let { exitCode, output } = await runPlaywrightCommand(childProcess, cwd, args, {
|
||||
async function runPlaywrightTest(childProcess: CommonFixtures['childProcess'], baseDir: string, params: any, env: NodeJS.ProcessEnv, options: RunOptions, files: Files, mergeReports: (reportFolder: string, env?: NodeJS.ProcessEnv, options?: RunOptions) => Promise<CliRunResult>, useIntermediateMergeReport: boolean): Promise<RunResult> {
|
||||
let reporter;
|
||||
if (useIntermediateMergeReport) {
|
||||
reporter = params.reporter;
|
||||
params.reporter = 'blob';
|
||||
}
|
||||
const reportFile = path.join(baseDir, 'report.json');
|
||||
const testProcess = startPlaywrightTest(childProcess, baseDir, params, {
|
||||
PW_TEST_REPORTER: path.join(__dirname, '../../packages/playwright-test/lib/reporters/json.js'),
|
||||
PLAYWRIGHT_JSON_OUTPUT_NAME: reportFile,
|
||||
...env,
|
||||
}, options.sendSIGINTAfter);
|
||||
}, options);
|
||||
const { exitCode } = await testProcess.exited;
|
||||
let output = testProcess.output.toString();
|
||||
|
||||
if (useIntermediateMergeReport) {
|
||||
const additionalArgs = [];
|
||||
@ -130,25 +137,14 @@ async function runPlaywrightTest(childProcess: CommonFixtures['childProcess'], b
|
||||
const config = configFile(baseDir, files);
|
||||
if (config)
|
||||
additionalArgs.push('--config', config);
|
||||
const cwd = options.cwd ? path.resolve(baseDir, options.cwd) : baseDir;
|
||||
const mergeResult = await mergeReports('blob-report', env, { cwd, additionalArgs });
|
||||
expect(mergeResult.exitCode).toBe(0);
|
||||
output = mergeResult.output;
|
||||
}
|
||||
|
||||
const summary = (re: RegExp) => {
|
||||
let result = 0;
|
||||
let match = re.exec(output);
|
||||
while (match) {
|
||||
result += (+match[1]);
|
||||
match = re.exec(output);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
const passed = summary(/(\d+) passed/g);
|
||||
const failed = summary(/(\d+) failed/g);
|
||||
const flaky = summary(/(\d+) flaky/g);
|
||||
const skipped = summary(/(\d+) skipped/g);
|
||||
const interrupted = summary(/(\d+) interrupted/g);
|
||||
const parsed = parseTestRunnerOutput(output);
|
||||
|
||||
let report;
|
||||
try {
|
||||
report = JSON.parse(fs.readFileSync(reportFile).toString());
|
||||
@ -171,66 +167,23 @@ async function runPlaywrightTest(childProcess: CommonFixtures['childProcess'], b
|
||||
if (report)
|
||||
visitSuites(report.suites);
|
||||
|
||||
const strippedOutput = stripAnsi(output);
|
||||
return {
|
||||
...parsed,
|
||||
exitCode,
|
||||
output: strippedOutput,
|
||||
outputLines: strippedOutput.split('\n').filter(line => line.startsWith('%%')).map(line => line.substring(2).trim()),
|
||||
rawOutput: output,
|
||||
passed,
|
||||
failed,
|
||||
flaky,
|
||||
skipped,
|
||||
interrupted,
|
||||
report,
|
||||
results,
|
||||
};
|
||||
}
|
||||
|
||||
async function runPlaywrightListFiles(childProcess: CommonFixtures['childProcess'], baseDir: string, env: NodeJS.ProcessEnv): Promise<{ output: string, exitCode: number }> {
|
||||
const reportFile = path.join(baseDir, 'report.json');
|
||||
// eslint-disable-next-line prefer-const
|
||||
let { exitCode, output } = await runPlaywrightCommand(childProcess, baseDir, ['list-files'], {
|
||||
PW_TEST_REPORTER: path.join(__dirname, '../../packages/playwright-test/lib/reporters/json.js'),
|
||||
PLAYWRIGHT_JSON_OUTPUT_NAME: reportFile,
|
||||
...env,
|
||||
});
|
||||
return { exitCode, output };
|
||||
}
|
||||
|
||||
function watchPlaywrightTest(childProcess: CommonFixtures['childProcess'], baseDir: string, env: NodeJS.ProcessEnv, options: RunOptions): TestChildProcess {
|
||||
const args = ['test', '--workers=2'];
|
||||
if (options.additionalArgs)
|
||||
args.push(...options.additionalArgs);
|
||||
const cwd = options.cwd ? path.resolve(baseDir, options.cwd) : baseDir;
|
||||
|
||||
const command = ['node', cliEntrypoint];
|
||||
command.push(...args);
|
||||
const testProcess = childProcess({
|
||||
command,
|
||||
env: cleanEnv({ PWTEST_WATCH: '1', ...env }),
|
||||
cwd,
|
||||
});
|
||||
return testProcess;
|
||||
}
|
||||
|
||||
async function runPlaywrightCommand(childProcess: CommonFixtures['childProcess'], cwd: string, commandWithArguments: string[], env: NodeJS.ProcessEnv, sendSIGINTAfter?: number): Promise<CliRunResult> {
|
||||
const command = ['node', cliEntrypoint];
|
||||
command.push(...commandWithArguments);
|
||||
const testProcess = childProcess({
|
||||
command,
|
||||
command: ['node', cliEntrypoint, 'list-files'],
|
||||
env: cleanEnv(env),
|
||||
cwd,
|
||||
cwd: baseDir,
|
||||
});
|
||||
let didSendSigint = false;
|
||||
testProcess.onOutput = () => {
|
||||
if (sendSIGINTAfter && !didSendSigint && countTimes(testProcess.output, '%%SEND-SIGINT%%') >= sendSIGINTAfter) {
|
||||
didSendSigint = true;
|
||||
process.kill(testProcess.process.pid!, 'SIGINT');
|
||||
}
|
||||
};
|
||||
const { exitCode } = await testProcess.exited;
|
||||
return { exitCode, output: testProcess.output.toString() };
|
||||
return { exitCode, output: testProcess.output };
|
||||
}
|
||||
|
||||
export function cleanEnv(env: NodeJS.ProcessEnv): NodeJS.ProcessEnv {
|
||||
@ -261,7 +214,6 @@ export function cleanEnv(env: NodeJS.ProcessEnv): NodeJS.ProcessEnv {
|
||||
}
|
||||
|
||||
export type RunOptions = {
|
||||
sendSIGINTAfter?: number;
|
||||
additionalArgs?: string[];
|
||||
cwd?: string,
|
||||
};
|
||||
@ -271,6 +223,7 @@ type Fixtures = {
|
||||
runInlineTest: (files: Files, params?: Params, env?: NodeJS.ProcessEnv, options?: RunOptions) => Promise<RunResult>;
|
||||
runListFiles: (files: Files) => Promise<{ output: string, exitCode: number }>;
|
||||
runWatchTest: (files: Files, env?: NodeJS.ProcessEnv, options?: RunOptions) => Promise<TestChildProcess>;
|
||||
interactWithTestRunner: (files: Files, params?: Params, env?: NodeJS.ProcessEnv, options?: RunOptions) => Promise<TestChildProcess>;
|
||||
runTSC: (files: Files) => Promise<TSCResult>;
|
||||
mergeReports: (reportFolder: string, env?: NodeJS.ProcessEnv, options?: RunOptions) => Promise<CliRunResult>
|
||||
useIntermediateMergeReport: boolean;
|
||||
@ -310,12 +263,16 @@ export const test = base
|
||||
await rimraf(cacheDir);
|
||||
},
|
||||
|
||||
runWatchTest: async ({ childProcess }, use, testInfo: TestInfo) => {
|
||||
runWatchTest: async ({ interactWithTestRunner }, use, testInfo: TestInfo) => {
|
||||
await use((files, env, options) => interactWithTestRunner(files, {}, { ...env, PWTEST_WATCH: '1' }, options));
|
||||
},
|
||||
|
||||
interactWithTestRunner: async ({ childProcess }, use, testInfo: TestInfo) => {
|
||||
const cacheDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'playwright-test-cache-'));
|
||||
let testProcess: TestChildProcess | undefined;
|
||||
await use(async (files: Files, env: NodeJS.ProcessEnv = {}, options: RunOptions = {}) => {
|
||||
await use(async (files: Files, params: Params = {}, env: NodeJS.ProcessEnv = {}, options: RunOptions = {}) => {
|
||||
const baseDir = await writeFiles(testInfo, files, true);
|
||||
testProcess = watchPlaywrightTest(childProcess, baseDir, { ...env, PWTEST_CACHE_DIR: cacheDir }, options);
|
||||
testProcess = startPlaywrightTest(childProcess, baseDir, params, { ...env, PWTEST_CACHE_DIR: cacheDir }, options);
|
||||
return testProcess;
|
||||
});
|
||||
await testProcess?.kill();
|
||||
@ -388,18 +345,6 @@ export function stripAnsi(str: string): string {
|
||||
return str.replace(asciiRegex, '');
|
||||
}
|
||||
|
||||
export function countTimes(s: string, sub: string): number {
|
||||
let result = 0;
|
||||
for (let index = 0; index !== -1;) {
|
||||
index = s.indexOf(sub, index);
|
||||
if (index !== -1) {
|
||||
result++;
|
||||
index += sub.length;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export function createImage(width: number, height: number, r: number = 0, g: number = 0, b: number = 0, a: number = 255): Buffer {
|
||||
const image = new PNG({ width, height });
|
||||
// Make both images red.
|
||||
@ -446,3 +391,32 @@ export function expectTestHelper(result: RunResult) {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function parseTestRunnerOutput(output: string) {
|
||||
const summary = (re: RegExp) => {
|
||||
let result = 0;
|
||||
let match = re.exec(output);
|
||||
while (match) {
|
||||
result += (+match[1]);
|
||||
match = re.exec(output);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
const passed = summary(/(\d+) passed/g);
|
||||
const failed = summary(/(\d+) failed/g);
|
||||
const flaky = summary(/(\d+) flaky/g);
|
||||
const skipped = summary(/(\d+) skipped/g);
|
||||
const interrupted = summary(/(\d+) interrupted/g);
|
||||
|
||||
const strippedOutput = stripAnsi(output);
|
||||
return {
|
||||
output: strippedOutput,
|
||||
outputLines: strippedOutput.split('\n').filter(line => line.startsWith('%%')).map(line => line.substring(2).trim()),
|
||||
rawOutput: output,
|
||||
passed,
|
||||
failed,
|
||||
flaky,
|
||||
skipped,
|
||||
interrupted,
|
||||
};
|
||||
}
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { test, expect } from './playwright-test-fixtures';
|
||||
import { test, expect, parseTestRunnerOutput } from './playwright-test-fixtures';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { spawnSync } from 'child_process';
|
||||
@ -431,10 +431,10 @@ test('should throw when using page in beforeAll', async ({ runInlineTest }) => {
|
||||
expect(result.output).toContain(`Error: "context" and "page" fixtures are not supported in "beforeAll"`);
|
||||
});
|
||||
|
||||
test('should report click error on sigint', async ({ runInlineTest }) => {
|
||||
test('should report click error on sigint', async ({ interactWithTestRunner }) => {
|
||||
test.skip(process.platform === 'win32', 'No sending SIGINT on Windows');
|
||||
|
||||
const result = await runInlineTest({
|
||||
const testProcess = await interactWithTestRunner({
|
||||
'a.test.ts': `
|
||||
import { test, expect } from '@playwright/test';
|
||||
test('timedout', async ({ page }) => {
|
||||
@ -445,9 +445,13 @@ test('should report click error on sigint', async ({ runInlineTest }) => {
|
||||
await promise;
|
||||
});
|
||||
`,
|
||||
}, { workers: 1 }, {}, { sendSIGINTAfter: 1 });
|
||||
}, { workers: 1 });
|
||||
await testProcess.waitForOutput('%%SEND-SIGINT%%');
|
||||
process.kill(testProcess.process.pid!, 'SIGINT');
|
||||
const { exitCode } = await testProcess.exited;
|
||||
expect(exitCode).toBe(130);
|
||||
|
||||
expect(result.exitCode).toBe(130);
|
||||
const result = parseTestRunnerOutput(testProcess.output);
|
||||
expect(result.passed).toBe(0);
|
||||
expect(result.failed).toBe(0);
|
||||
expect(result.interrupted).toBe(1);
|
||||
|
||||
@ -13,8 +13,10 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { test, expect } from './playwright-test-fixtures';
|
||||
import { test, expect, parseTestRunnerOutput } from './playwright-test-fixtures';
|
||||
|
||||
test('it should not allow multiple tests with the same name per suite', async ({ runInlineTest }) => {
|
||||
const result = await runInlineTest({
|
||||
@ -93,10 +95,10 @@ test('should continue with other tests after worker process suddenly exits', asy
|
||||
expect(result.output).toContain('Internal error: worker process exited unexpectedly');
|
||||
});
|
||||
|
||||
test('sigint should stop workers', async ({ runInlineTest }) => {
|
||||
test('sigint should stop workers', async ({ interactWithTestRunner }) => {
|
||||
test.skip(process.platform === 'win32', 'No sending SIGINT on Windows');
|
||||
|
||||
const result = await runInlineTest({
|
||||
const testProcess = await interactWithTestRunner({
|
||||
'a.spec.js': `
|
||||
import { test, expect } from '@playwright/test';
|
||||
test('interrupted1', async () => {
|
||||
@ -117,8 +119,16 @@ test('sigint should stop workers', async ({ runInlineTest }) => {
|
||||
console.log('\\n%%skipped2');
|
||||
});
|
||||
`,
|
||||
}, { 'workers': 2, 'reporter': 'line,json' }, {}, { sendSIGINTAfter: 2 });
|
||||
expect(result.exitCode).toBe(130);
|
||||
}, { 'workers': 2, 'reporter': 'line,json' }, {
|
||||
PW_TEST_REPORTER: path.join(__dirname, '../../packages/playwright-test/lib/reporters/json.js'),
|
||||
PLAYWRIGHT_JSON_OUTPUT_NAME: 'report.json',
|
||||
});
|
||||
await testProcess.waitForOutput('%%SEND-SIGINT%%', 2);
|
||||
process.kill(testProcess.process.pid!, 'SIGINT');
|
||||
const { exitCode } = await testProcess.exited;
|
||||
expect(exitCode).toBe(130);
|
||||
|
||||
const result = parseTestRunnerOutput(testProcess.output);
|
||||
expect(result.passed).toBe(0);
|
||||
expect(result.failed).toBe(0);
|
||||
expect(result.skipped).toBe(2);
|
||||
@ -130,11 +140,12 @@ test('sigint should stop workers', async ({ runInlineTest }) => {
|
||||
expect(result.output).toContain('Test was interrupted.');
|
||||
expect(result.output).not.toContain('Test timeout of');
|
||||
|
||||
const interrupted2 = result.report.suites[1].specs[0];
|
||||
const report = JSON.parse(fs.readFileSync(test.info().outputPath('report.json'), 'utf8'));
|
||||
const interrupted2 = report.suites[1].specs[0];
|
||||
expect(interrupted2.title).toBe('interrupted2');
|
||||
expect(interrupted2.tests[0].results[0].workerIndex === 0 || interrupted2.tests[0].results[0].workerIndex === 1).toBe(true);
|
||||
|
||||
const skipped2 = result.report.suites[1].specs[1];
|
||||
const skipped2 = report.suites[1].specs[1];
|
||||
expect(skipped2.title).toBe('skipped2');
|
||||
expect(skipped2.tests[0].results[0].workerIndex).toBe(-1);
|
||||
});
|
||||
@ -169,10 +180,10 @@ test('should use the first occurring error when an unhandled exception was throw
|
||||
expect(result.report.suites[0].specs[0].tests[0].results[0].error!.message).toBe('first error');
|
||||
});
|
||||
|
||||
test('worker interrupt should report errors', async ({ runInlineTest }) => {
|
||||
test('worker interrupt should report errors', async ({ interactWithTestRunner }) => {
|
||||
test.skip(process.platform === 'win32', 'No sending SIGINT on Windows');
|
||||
|
||||
const result = await runInlineTest({
|
||||
const testProcess = await interactWithTestRunner({
|
||||
'a.spec.ts': `
|
||||
import { test as base, expect } from '@playwright/test';
|
||||
const test = base.extend({
|
||||
@ -187,8 +198,13 @@ test('worker interrupt should report errors', async ({ runInlineTest }) => {
|
||||
await throwOnTeardown;
|
||||
});
|
||||
`,
|
||||
}, {}, {}, { sendSIGINTAfter: 1 });
|
||||
expect(result.exitCode).toBe(130);
|
||||
});
|
||||
await testProcess.waitForOutput('%%SEND-SIGINT%%');
|
||||
process.kill(testProcess.process.pid!, 'SIGINT');
|
||||
const { exitCode } = await testProcess.exited;
|
||||
expect(exitCode).toBe(130);
|
||||
|
||||
const result = parseTestRunnerOutput(testProcess.output);
|
||||
expect(result.passed).toBe(0);
|
||||
expect(result.failed).toBe(0);
|
||||
expect(result.interrupted).toBe(1);
|
||||
@ -334,10 +350,10 @@ test('should not hang if test suites in worker are inconsistent with runner', as
|
||||
expect(result.report.suites[0].specs[1].tests[0].results[0].error!.message).toBe('Test(s) not found in the worker process. Make sure test titles do not change:\nproject-name > a.spec.js > Test 1 - bar\nproject-name > a.spec.js > Test 2 - baz');
|
||||
});
|
||||
|
||||
test('sigint should stop global setup', async ({ runInlineTest }) => {
|
||||
test('sigint should stop global setup', async ({ interactWithTestRunner }) => {
|
||||
test.skip(process.platform === 'win32', 'No sending SIGINT on Windows');
|
||||
|
||||
const result = await runInlineTest({
|
||||
const testProcess = await interactWithTestRunner({
|
||||
'playwright.config.ts': `
|
||||
module.exports = {
|
||||
globalSetup: './globalSetup',
|
||||
@ -360,18 +376,22 @@ test('sigint should stop global setup', async ({ runInlineTest }) => {
|
||||
import { test, expect } from '@playwright/test';
|
||||
test('test', async () => { });
|
||||
`,
|
||||
}, { 'workers': 1 }, {}, { sendSIGINTAfter: 1 });
|
||||
expect(result.exitCode).toBe(130);
|
||||
}, { 'workers': 1 });
|
||||
await testProcess.waitForOutput('%%SEND-SIGINT%%');
|
||||
process.kill(testProcess.process.pid!, 'SIGINT');
|
||||
const { exitCode } = await testProcess.exited;
|
||||
expect(exitCode).toBe(130);
|
||||
|
||||
const result = parseTestRunnerOutput(testProcess.output);
|
||||
expect(result.passed).toBe(0);
|
||||
const output = result.output;
|
||||
expect(output).toContain('Global setup');
|
||||
expect(output).not.toContain('Global teardown');
|
||||
expect(result.output).toContain('Global setup');
|
||||
expect(result.output).not.toContain('Global teardown');
|
||||
});
|
||||
|
||||
test('sigint should stop plugins', async ({ runInlineTest }) => {
|
||||
test('sigint should stop plugins', async ({ interactWithTestRunner }) => {
|
||||
test.skip(process.platform === 'win32', 'No sending SIGINT on Windows');
|
||||
|
||||
const result = await runInlineTest({
|
||||
const testProcess = await interactWithTestRunner({
|
||||
'playwright.config.ts': `
|
||||
const _plugins = [];
|
||||
_plugins.push(() => ({
|
||||
@ -403,21 +423,25 @@ test('sigint should stop plugins', async ({ runInlineTest }) => {
|
||||
console.log('testing!');
|
||||
});
|
||||
`,
|
||||
}, { 'workers': 1 }, {}, { sendSIGINTAfter: 1 });
|
||||
expect(result.exitCode).toBe(130);
|
||||
}, { 'workers': 1 });
|
||||
await testProcess.waitForOutput('%%SEND-SIGINT%%');
|
||||
process.kill(testProcess.process.pid!, 'SIGINT');
|
||||
const { exitCode } = await testProcess.exited;
|
||||
expect(exitCode).toBe(130);
|
||||
|
||||
const result = parseTestRunnerOutput(testProcess.output);
|
||||
expect(result.passed).toBe(0);
|
||||
const output = result.output;
|
||||
expect(output).toContain('Plugin1 setup');
|
||||
expect(output).toContain('Plugin1 teardown');
|
||||
expect(output).not.toContain('Plugin2 setup');
|
||||
expect(output).not.toContain('Plugin2 teardown');
|
||||
expect(output).not.toContain('testing!');
|
||||
expect(result.output).toContain('Plugin1 setup');
|
||||
expect(result.output).toContain('Plugin1 teardown');
|
||||
expect(result.output).not.toContain('Plugin2 setup');
|
||||
expect(result.output).not.toContain('Plugin2 teardown');
|
||||
expect(result.output).not.toContain('testing!');
|
||||
});
|
||||
|
||||
test('sigint should stop plugins 2', async ({ runInlineTest }) => {
|
||||
test('sigint should stop plugins 2', async ({ interactWithTestRunner }) => {
|
||||
test.skip(process.platform === 'win32', 'No sending SIGINT on Windows');
|
||||
|
||||
const result = await runInlineTest({
|
||||
const testProcess = await interactWithTestRunner({
|
||||
'playwright.config.ts': `
|
||||
const _plugins = [];
|
||||
_plugins.push(() => ({
|
||||
@ -447,15 +471,19 @@ test('sigint should stop plugins 2', async ({ runInlineTest }) => {
|
||||
console.log('testing!');
|
||||
});
|
||||
`,
|
||||
}, { 'workers': 1 }, {}, { sendSIGINTAfter: 1 });
|
||||
expect(result.exitCode).toBe(130);
|
||||
}, { 'workers': 1 });
|
||||
await testProcess.waitForOutput('%%SEND-SIGINT%%');
|
||||
process.kill(testProcess.process.pid!, 'SIGINT');
|
||||
const { exitCode } = await testProcess.exited;
|
||||
expect(exitCode).toBe(130);
|
||||
|
||||
const result = parseTestRunnerOutput(testProcess.output);
|
||||
expect(result.passed).toBe(0);
|
||||
const output = result.output;
|
||||
expect(output).toContain('Plugin1 setup');
|
||||
expect(output).toContain('Plugin2 setup');
|
||||
expect(output).toContain('Plugin1 teardown');
|
||||
expect(output).toContain('Plugin2 teardown');
|
||||
expect(output).not.toContain('testing!');
|
||||
expect(result.output).toContain('Plugin1 setup');
|
||||
expect(result.output).toContain('Plugin2 setup');
|
||||
expect(result.output).toContain('Plugin1 teardown');
|
||||
expect(result.output).toContain('Plugin2 teardown');
|
||||
expect(result.output).not.toContain('testing!');
|
||||
});
|
||||
|
||||
test('should not crash with duplicate titles and .only', async ({ runInlineTest }) => {
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
|
||||
import type http from 'http';
|
||||
import path from 'path';
|
||||
import { test, expect } from './playwright-test-fixtures';
|
||||
import { test, expect, parseTestRunnerOutput } from './playwright-test-fixtures';
|
||||
import { createHttpServer } from '../../packages/playwright-core/lib/utils/network';
|
||||
|
||||
const SIMPLE_SERVER_PATH = path.join(__dirname, 'assets', 'simple-server.js');
|
||||
@ -705,10 +705,10 @@ test('should be able to ignore "stderr"', async ({ runInlineTest }, { workerInde
|
||||
expect(result.output).not.toContain('error from server');
|
||||
});
|
||||
|
||||
test('should forward stdout when set to "pipe" before server is ready', async ({ runInlineTest }, { workerIndex }) => {
|
||||
test('should forward stdout when set to "pipe" before server is ready', async ({ interactWithTestRunner }) => {
|
||||
test.skip(process.platform === 'win32', 'No sending SIGINT on Windows');
|
||||
|
||||
const result = await runInlineTest({
|
||||
const testProcess = await interactWithTestRunner({
|
||||
'web-server.js': `
|
||||
console.log('output from server');
|
||||
console.log('\\n%%SEND-SIGINT%%');
|
||||
@ -728,7 +728,12 @@ test('should forward stdout when set to "pipe" before server is ready', async ({
|
||||
},
|
||||
};
|
||||
`,
|
||||
}, { workers: 1 }, {}, { sendSIGINTAfter: 1 });
|
||||
}, { workers: 1 });
|
||||
await testProcess.waitForOutput('%%SEND-SIGINT%%');
|
||||
process.kill(testProcess.process.pid!, 'SIGINT');
|
||||
await testProcess.exited;
|
||||
|
||||
const result = parseTestRunnerOutput(testProcess.output);
|
||||
expect(result.passed).toBe(0);
|
||||
expect(result.output).toContain('[WebServer] output from server');
|
||||
expect(result.output).not.toContain('Timed out waiting 3000ms');
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user