chore: implement --no-deps (#20569)

This commit is contained in:
Pavel Feldman 2023-02-01 16:32:13 -08:00 committed by GitHub
parent cb9ace6035
commit 421dd884a7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 46 additions and 10 deletions

View File

@ -91,8 +91,11 @@ export default defineConfig({
List of projects that need to run before any test in this project runs. Dependencies can
be useful for configuring the global setup actions in a way that every action is
in a form of a test. That way one can record traces and other artifacts for the
global setup routine, see the setup steps in the test report, etc.
in a form of a test. Passing `--no-deps` argument ignores the dependencies and
behaves as if they were not specified.
Using dependencies allows global setup to produce traces and other artifacts,
see the setup steps in the test report, etc.
For example:
@ -105,7 +108,6 @@ export default defineConfig({
{
name: 'setup',
testMatch: /global.setup\.ts/,
dependencies: ['setup'],
},
{
name: 'chromium',

View File

@ -50,6 +50,7 @@ function addTestCommand(program: Command) {
command.option('-j, --workers <workers>', `Number of concurrent workers or percentage of logical CPU cores, use 1 to run in a single worker (default: 50%)`);
command.option('--list', `Collect all the tests and report them, but do not run`);
command.option('--max-failures <N>', `Stop after the first N failures`);
command.option('--no-deps', 'Do not run project dependencies');
command.option('--output <dir>', `Folder for output artifacts (default: "test-results")`);
command.option('--pass-with-no-tests', `Makes test run succeed even if no tests were found`);
command.option('--quiet', `Suppress stdio`);
@ -154,6 +155,8 @@ async function runTests(args: string[], opts: { [key: string]: any }) {
await configLoader.loadConfigFile(resolvedConfigFile);
else
await configLoader.loadEmptyConfig(configFileOrDirectory);
if (opts.deps === false)
configLoader.ignoreProjectDependencies();
const config = configLoader.fullConfig();
config._internal.testFileFilters = args.map(arg => {

View File

@ -151,6 +151,11 @@ export class ConfigLoader {
this._assignUniqueProjectIds(this._fullConfig.projects);
}
ignoreProjectDependencies() {
for (const project of this._fullConfig.projects)
project._internal.deps = [];
}
private _assignUniqueProjectIds(projects: FullProjectInternal[]) {
const usedNames = new Set();
for (const p of projects) {

View File

@ -187,8 +187,11 @@ export interface FullProject<TestArgs = {}, WorkerArgs = {}> {
name: string;
/**
* List of projects that need to run before any test in this project runs. Dependencies can be useful for configuring
* the global setup actions in a way that every action is in a form of a test. That way one can record traces and
* other artifacts for the global setup routine, see the setup steps in the test report, etc.
* the global setup actions in a way that every action is in a form of a test. Passing `--no-deps` argument ignores
* the dependencies and behaves as if they were not specified.
*
* Using dependencies allows global setup to produce traces and other artifacts, see the setup steps in the test
* report, etc.
*
* For example:
*
@ -201,7 +204,6 @@ export interface FullProject<TestArgs = {}, WorkerArgs = {}> {
* {
* name: 'setup',
* testMatch: /global.setup\.ts/,
* dependencies: ['setup'],
* },
* {
* name: 'chromium',
@ -5039,8 +5041,11 @@ export interface TestInfoError {
interface TestProject {
/**
* List of projects that need to run before any test in this project runs. Dependencies can be useful for configuring
* the global setup actions in a way that every action is in a form of a test. That way one can record traces and
* other artifacts for the global setup routine, see the setup steps in the test report, etc.
* the global setup actions in a way that every action is in a form of a test. Passing `--no-deps` argument ignores
* the dependencies and behaves as if they were not specified.
*
* Using dependencies allows global setup to produce traces and other artifacts, see the setup steps in the test
* report, etc.
*
* For example:
*
@ -5053,7 +5058,6 @@ interface TestProject {
* {
* name: 'setup',
* testMatch: /global.setup\.ts/,
* dependencies: ['setup'],
* },
* {
* name: 'chromium',

View File

@ -32,12 +32,34 @@ test('should run projects with dependencies', async ({ runInlineTest }) => {
console.log('\\n%%' + testInfo.project.name);
});
`,
}, { workers: 1 });
}, { workers: 1 }, undefined, { additionalArgs: ['--project=B', '--project=C'] });
expect(result.exitCode).toBe(0);
expect(result.passed).toBe(3);
expect(extractLines(result.output)).toEqual(['A', 'B', 'C']);
});
test('should not run projects with dependencies when --no-deps is passed', async ({ runInlineTest }) => {
const result = await runInlineTest({
'playwright.config.ts': `
module.exports = {
projects: [
{ name: 'A' },
{ name: 'B', dependencies: ['A'] },
{ name: 'C', dependencies: ['A'] },
],
};`,
'test.spec.ts': `
const { test } = pwt;
test('test', async ({}, testInfo) => {
console.log('\\n%%' + testInfo.project.name);
});
`,
}, { workers: 1 }, undefined, { additionalArgs: ['--no-deps', '--project=B', '--project=C'] });
expect(result.exitCode).toBe(0);
expect(result.passed).toBe(2);
expect(extractLines(result.output)).toEqual(['B', 'C']);
});
test('should not run project if dependency failed', async ({ runInlineTest }) => {
const result = await runInlineTest({
'playwright.config.ts': `