forked from angular/components
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathrun-component-tests.js
162 lines (143 loc) · 5.7 KB
/
run-component-tests.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#!/usr/bin/env node
/**
* Script that simplifies the workflow of running unit tests for a component
* using Bazel. Here are a few examples:
*
* node ./scripts/run-component-tests all | Runs tests for all components
* node ./scripts/run-component-tests button | Runs Material button tests
* node ./scripts/run-component-tests overlay | Runs CDK overlay tests
* node ./scripts/run-component-tests src/cdk/a11y | Runs CDK a11y tests
* node ./scripts/run-component-tests a11y overlay | Runs CDK a11y and overlay tests
*
* Supported command line flags:
*
* --debug | If specified, no browser will be launched.
* --firefox | Instead of Chrome being used for tests, Firefox will be used.
* --no-watch | Watch mode is enabled by default. This flag opts-out to standard Bazel.
*/
const yargs = require('yargs');
const shelljs = require('shelljs');
const chalk = require('chalk');
const path = require('path');
const args = process.argv.slice(2);
const {guessPackageName, convertPathToPosix} = require('./util');
// Path to the project directory.
const projectDir = path.join(__dirname, '../');
// Path to the directory that contains all packages.
const packagesDir = path.join(projectDir, 'src/');
// ShellJS should exit if any command fails.
shelljs.set('-e');
shelljs.cd(projectDir);
// Extracts the supported command line options.
const {components, debug, firefox, watch} = yargs(args)
.command('* <components..>', 'Run tests for specified components', args =>
args.positional('components', {type: 'array'}),
)
.option('debug', {
alias: 'local',
type: 'boolean',
description: 'Whether test should run in debug mode. You can manually connect a browser then.',
})
.option('firefox', {
type: 'boolean',
description: 'Whether browser tests should run within Firefox.',
})
.option('watch', {
type: 'boolean',
default: true,
description: 'Whether tests should be re-run automatically upon changes.',
})
.strict()
.parseSync();
// Whether tests for all components should be run.
const all = components.length === 1 && components[0] === 'all';
// We can only run a single target with "--debug". Running multiple targets within the
// same Karma server is not possible since each test target runs isolated from the others.
if (debug && (components.length > 1 || all)) {
console.error(
chalk.red(
'Unable to run multiple components tests in debug mode. ' +
'Only one component at a time can be run with "--debug"',
),
);
process.exit(1);
}
const browserName = firefox ? 'firefox' : 'chromium';
const bazelBinary = `pnpm -s ${watch ? 'ibazel' : 'bazel'}`;
// If `all` has been specified as component, we run tests for all components
// in the repository. The `--firefox` flag can be still specified.
if (all) {
// `ibazel` doesn't allow us to filter tests and build targets as it only allows
// a subset of Bazel flags to be passed through. We temporarily always use `bazel`
// instead of ibazel until https://github.com/bazelbuild/bazel-watcher/pull/382 lands.
if (watch) {
console.warn(chalk.yellow('Unable to run all component tests in watch mode.'));
console.warn(chalk.yellow('Tests will be run in non-watch mode..'));
}
shelljs.exec(
`pnpm -s bazel test --test_tag_filters=-e2e,browser:${browserName} ` +
`--build_tag_filters=browser:${browserName} --build_tests_only //src/...`,
);
return;
}
// Exit if no component has been specified.
if (!components.length) {
console.error(
chalk.red(
'No component specified. Please either specify individual components, or pass "all" ' +
'in order to run tests for all components.',
),
);
console.info(chalk.yellow('Below are a few examples of how the script can be run:'));
console.info(chalk.yellow(` - pnpm test all`));
console.info(chalk.yellow(` - pnpm test cdk/overlay material/stepper`));
console.info(chalk.yellow(` - pnpm test button toolbar`));
process.exit(1);
}
const bazelAction = debug ? 'run' : 'test';
const testLabels = components.map(t => `${getBazelPackageOfComponentName(t)}:${getTargetName(t)}`);
// Runs Bazel for the determined test labels.
shelljs.exec(`${bazelBinary} ${bazelAction} ${testLabels.join(' ')}`);
/**
* Gets the Bazel package label for the specified component name. Throws if
* the component could not be resolved to a Bazel package.
*/
function getBazelPackageOfComponentName(name) {
// Before guessing any Bazel package, we test if the name contains the
// package name already. If so, we just use that for Bazel package.
const targetName =
convertPathToBazelLabel(name) || convertPathToBazelLabel(path.join(packagesDir, name));
if (targetName !== null) {
return targetName;
}
// If the name does not contain an explicit package name, try to guess it.
const guess = guessPackageName(name, packagesDir);
const guessLabel = guess.result
? convertPathToBazelLabel(path.join(packagesDir, guess.result))
: null;
if (guessLabel) {
return guessLabel;
}
console.error(
chalk.red(
`Could not find test target for specified component: ` +
`${chalk.yellow(name)}. Looked in packages: \n${guess.attempts.join('\n')}`,
),
);
process.exit(1);
}
/** Converts a path to a Bazel label. */
function convertPathToBazelLabel(name) {
if (shelljs.test('-d', name)) {
return `//${convertPathToPosix(path.relative(projectDir, name))}`;
}
return null;
}
/** Gets the name of the target that should be run. */
function getTargetName(packageName) {
// Schematics don't have _debug and browser targets.
if (packageName && packageName.endsWith('schematics')) {
return 'unit_tests';
}
return `unit_tests_${debug ? 'debug' : browserName}`;
}