mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-14 16:52:26 +08:00

The docker script does not exit with the correct exit code when invoking commends in `execa`. You can verify this by changing `npm run test.e2e` in the script to `npm run foo` (a non-existent script). The underlying command will fail, but the parent script will still exit with exit code 0. Important: The tests themselves have always errored correctly, so this does not impact test execution. Only the invocation of the test command is impacted. This PR ensures that invoking the wrong command causes the parent script to exit with the correct code. Co-authored-by: Brandy Carney <brandyscarney@gmail.com>
60 lines
2.4 KiB
JavaScript
60 lines
2.4 KiB
JavaScript
import { execa } from 'execa';
|
||
import * as fs from 'fs';
|
||
import { resolve } from 'path';
|
||
import chalk from 'chalk';
|
||
|
||
const removeNewline = (string) => {
|
||
return string.replace(/(\r\n|\n|\r)/gm, "");
|
||
}
|
||
|
||
const readConfigFile = (file) => {
|
||
if (fs.existsSync(file)) {
|
||
return fs.readFileSync(file, { encoding: 'utf-8' });
|
||
}
|
||
|
||
return '';
|
||
}
|
||
|
||
// These files are optional, so we don't want to error if they don't exist
|
||
const display = removeNewline(readConfigFile('docker-display.txt'));
|
||
const displayVolume = removeNewline(readConfigFile('docker-display-volume.txt'));
|
||
|
||
// Using --mount requires an absolute path which is what this gives us.
|
||
const pwd = resolve('./');
|
||
|
||
/**
|
||
* -it will let the user gracefully kill the process using Ctrl+C (or equivalent)
|
||
* -e DISPLAY and -v handle configuration for headed mode
|
||
* --ipc=host is recommended when using Chromium to avoid out of memory crashes: https://playwright.dev/docs/ci#docker
|
||
* --init is recommended to avoid zombie processes: https://playwright.dev/docs/ci#docker
|
||
* --mount allow us to mount the local Ionic project inside of the Docker container so devs do not need to re-build the project in Docker.
|
||
*/
|
||
const args = ['run', '--rm', '--init', `-e DISPLAY=${display}`, `-v ${displayVolume}`, '--ipc=host', `--mount=type=bind,source=${pwd},target=/ionic`, 'ionic-playwright', 'npm run test.e2e --', ...process.argv.slice(2)];
|
||
|
||
// Set the CI env variable so Playwright uses the CI config
|
||
if (process.env.CI) {
|
||
args.splice(1, 0, '-e CI=true');
|
||
/**
|
||
* Otherwise, we should let the session be interactive locally. This will
|
||
* not work on CI which is why we do not apply it there.
|
||
*/
|
||
} else {
|
||
args.splice(1, 0, '-it');
|
||
}
|
||
|
||
/**
|
||
* While these config files are optional to run the tests, they are required to run
|
||
* the tests in headed mode. Add a warning if dev tries to run headed tests without
|
||
* the correct config files.
|
||
*/
|
||
const requestHeaded = process.argv.find(arg => arg.includes('headed'));
|
||
const hasHeadedConfigFiles = display && displayVolume;
|
||
if (requestHeaded && !hasHeadedConfigFiles) {
|
||
console.warn(chalk.yellow.bold('\n⚠️ You are running tests in headed mode, but one or more of your headed config files was not found.\nPlease ensure that both docker-display.txt and docker-display-volume.txt have been created in the correct location.\n'));
|
||
}
|
||
|
||
const res = await execa('docker', args, { shell: true, stdio: 'inherit' });
|
||
|
||
// If underlying scripts failed this whole process should fail too
|
||
process.exit(res.exitCode);
|