From 5db7ce5964dc083fd761ae5fd97529732c00789d Mon Sep 17 00:00:00 2001 From: pierscowburn Date: Tue, 15 Feb 2022 21:10:35 +0000 Subject: [PATCH] fix: propagate exit code in experimental mode (#12070) In experimental ESM mode a child process is forked in order to run the tests. Currently the exit code of this child process is not propagated to the exit code of the parent process, which means that the process exits with a status code of `0` even if some of the tests failed. This makes it difficult to use Playwright in CI in experimental mode, as the CI pipeline as a whole will pass despite the test failures. This change addresses this by propagating the exit code in the case where it is non-zero. --- packages/playwright-core/src/cli/cli.ts | 6 +++++- tests/playwright-test/loader.spec.ts | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/packages/playwright-core/src/cli/cli.ts b/packages/playwright-core/src/cli/cli.ts index 0da0cfd554..2b18e669fb 100755 --- a/packages/playwright-core/src/cli/cli.ts +++ b/packages/playwright-core/src/cli/cli.ts @@ -19,9 +19,13 @@ import { fork } from 'child_process'; if (process.env.PW_EXPERIMENTAL_TS_ESM) { const NODE_OPTIONS = (process.env.NODE_OPTIONS || '') + ` --experimental-loader=${require.resolve('@playwright/test/lib/experimentalLoader')}`; - fork(require.resolve('./innerCli'), process.argv.slice(2), { + const innerProcess = fork(require.resolve('./innerCli'), process.argv.slice(2), { env: { ...process.env, NODE_OPTIONS } }); + + innerProcess.on('close', code => { + if (code !== 0 && code !== null) process.exit(code); + }); } else { require('./innerCli'); } diff --git a/tests/playwright-test/loader.spec.ts b/tests/playwright-test/loader.spec.ts index 5aba8151a5..d596947b88 100644 --- a/tests/playwright-test/loader.spec.ts +++ b/tests/playwright-test/loader.spec.ts @@ -267,6 +267,24 @@ test('should import esm from ts when package.json has type module in experimenta expect(result.exitCode).toBe(0); }); +test('should propagate subprocess exit code in experimental mode', async ({ runInlineTest }) => { + // We only support experimental esm mode on Node 16+ + test.skip(parseInt(process.version.slice(1), 10) < 16); + const result = await runInlineTest({ + 'package.json': JSON.stringify({ type: 'module' }), + 'a.test.ts': ` + const { test } = pwt; + test('failing test', ({}, testInfo) => { + expect(1).toBe(2); + }); + `, + }, {}, { + PW_EXPERIMENTAL_TS_ESM: true + }); + + expect(result.exitCode).toBe(1); +}); + test('should filter stack trace for simple expect', async ({ runInlineTest }) => { const result = await runInlineTest({ 'expect-test.spec.ts': `