Skip to content

Commit 0f2ffda

Browse files
authored
Add test filters for selective test running (#2441)
* Add test filters for selective test running * Fix transpile-typescript:watch * Respond with an error rather than unregistering
1 parent 3063972 commit 0f2ffda

File tree

6 files changed

+94
-62
lines changed

6 files changed

+94
-62
lines changed

gulp-tasks/transpile-typescript.js

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,10 @@ const packagesDir = path.join(__dirname, '..', 'packages');
2929
* in the root package directory, along with the corresponding `.d.ts` files.
3030
*
3131
* @param {string} packageName
32+
* @param {Object} [options]
33+
* @param {boolean} [options.failOnError=true]
3234
*/
33-
const transpilePackage = async (packageName) => {
35+
const transpilePackage = async (packageName, {failOnError = true} = {}) => {
3436
try {
3537
// Compile TypeScript for the given project.
3638
// Reference the local `node_modules` version of `tsc` since on Windows
@@ -50,27 +52,30 @@ const transpilePackage = async (packageName) => {
5052
if (!(await fs.pathExists(mjsFile))) {
5153
const mjsSource = `export * from './${assetBasename}.js';`;
5254

53-
// console.log({mjsFile, tsFile, assetBasename})
5455
fs.outputFileSync(mjsFile, mjsSource);
5556
}
5657
}
5758
} catch (error) {
58-
logHelper.error(error.stdout);
59-
throw error;
59+
if (failOnError) {
60+
throw error;
61+
} else {
62+
logHelper.error(error.stdout);
63+
}
6064
}
6165
};
6266

6367
/**
6468
* Transpiles a package iff it has TypeScript source files.
6569
*
6670
* @param {string} packagePath
71+
* @param {Object} [options]
6772
*/
68-
const transpilePackageOrSkip = async (packagePath) => {
69-
// `packagePath` will be posix style because it comes from `glog()`.
73+
const transpilePackageOrSkip = async (packagePath, options) => {
74+
// `packagePath` will be posix style because it comes from `glob()`.
7075
const packageName = packagePath.split('/').slice(-1)[0];
7176

7277
if (await fs.pathExists(path.join(packagePath, 'tsconfig.json'))) {
73-
await queueTranspile(packageName);
78+
await queueTranspile(packageName, options);
7479
} else {
7580
logHelper.log(ol`Skipping package '${packageName}'
7681
not yet converted to typescript.`);
@@ -92,14 +97,16 @@ const debouncedTranspilerMap = {};
9297
* needed.
9398
*
9499
* @param {string} packageName
100+
* @param {Object} [options]
95101
*/
96-
const queueTranspile = async (packageName) => {
102+
const queueTranspile = async (packageName, options) => {
97103
if (!debouncedTranspilerMap[packageName]) {
98104
debouncedTranspilerMap[packageName] = new AsyncDebounce(async () => {
99-
await transpilePackage(packageName);
105+
await transpilePackage(packageName, options);
100106
});
101107
}
102108
await debouncedTranspilerMap[packageName].call();
109+
debouncedTranspilerMap[packageName] = null;
103110
};
104111

105112
/**
@@ -123,16 +130,13 @@ const needsTranspile = (packageName) => {
123130
gulp.task('transpile-typescript', gulp.series(packageRunnner(
124131
'transpile-typescript', 'all', transpilePackageOrSkip)));
125132

126-
gulp.task('transpile-typescript:watch', gulp.series(packageRunnner(
127-
'transpile-typescript', 'all', transpilePackageOrSkip)));
128-
129133
gulp.task('transpile-typescript:watch', () => {
130134
const watcher = gulp.watch(`./${global.packageOrStar}/workbox-*/src/**/*.ts`);
131135
watcher.on('all', async (event, file) => {
132136
const changedPkg = path.relative(packagesDir, file).split(path.sep)[0];
133137

134138
pendingChangesMap[changedPkg] = true;
135-
await queueTranspile(changedPkg);
139+
await queueTranspile(changedPkg, {failOnError: false});
136140
pendingChangesMap[changedPkg] = false;
137141
});
138142
});

infra/testing/helpers/extendable-event-utils.mjs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,13 @@ export const spyOnEvent = (event) => {
3333

3434
if (event instanceof FetchEvent) {
3535
event.respondWith = sinon.stub().callsFake((responseOrPromise) => {
36-
eventResponses.set(event, responseOrPromise);
37-
promises.push(Promise.resolve(responseOrPromise));
36+
const promise = Promise.resolve(responseOrPromise);
37+
38+
eventResponses.set(event, promise);
39+
promises.push(promise);
3840

3941
// TODO(philipwalton): we cannot currently call the native
40-
// `respondWith()` due to this bug in Firefix:
42+
// `respondWith()` due to this bug in Firefox:
4143
// https://bugzilla.mozilla.org/show_bug.cgi?id=1538756
4244
// FetchEvent.prototype.respondWith.call(event, responseOrPromise);
4345
});

infra/testing/server/routes/sw-bundle.js

Lines changed: 49 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -26,44 +26,59 @@ async function handler(req, res) {
2626
const env = process.env.NODE_ENV || 'development';
2727
const packageName = req.params.package;
2828

29-
// Ensure the TypeScript transpile step has completed first.
30-
if (needsTranspile(packageName)) {
31-
await queueTranspile(packageName);
32-
}
29+
res.set('Content-Type', 'text/javascript');
3330

34-
const bundle = await rollup({
35-
input: `./test/${packageName}/sw/**/test-*.mjs`,
36-
plugins: [
37-
multiEntry(),
38-
resolve({
39-
customResolveOptions: {
40-
moduleDirectory: 'packages',
41-
},
42-
}),
43-
// TODO(philipwalton): some of our shared testing helpers use commonjs
44-
// so we have to support this for the time being.
45-
commonjs({
46-
exclude: '*.mjs',
47-
}),
48-
replace({
49-
'process.env.NODE_ENV': JSON.stringify(env),
50-
'BROWSER_NAMESPACES': JSON.stringify(BROWSER_NAMESPACES),
51-
'WORKBOX_CDN_ROOT_URL': '/__WORKBOX/buildFile',
52-
}),
53-
],
54-
cache: caches[env],
55-
});
31+
try {
32+
// Ensure the TypeScript transpile step has completed first.
33+
if (needsTranspile(packageName)) {
34+
await queueTranspile(packageName);
35+
}
5636

57-
// Update the cache so subsequent bundles are faster, and make sure it
58-
// keep the dev/prod caches separate since the source files won't change
59-
// between those builds, but the outputs will.
60-
caches[env] = bundle.cache;
37+
// Allows you to selectively run tests by adding the `?test=` to the URL.
38+
const testFilter = req.query.filter || '**/test-*.mjs';
39+
const bundle = await rollup({
40+
input: `./test/${packageName}/sw/` + testFilter,
41+
plugins: [
42+
multiEntry(),
43+
resolve({
44+
customResolveOptions: {
45+
moduleDirectory: 'packages',
46+
},
47+
}),
48+
// TODO(philipwalton): some of our shared testing helpers use commonjs
49+
// so we have to support this for the time being.
50+
commonjs({
51+
exclude: '*.mjs',
52+
}),
53+
replace({
54+
'process.env.NODE_ENV': JSON.stringify(env),
55+
'BROWSER_NAMESPACES': JSON.stringify(BROWSER_NAMESPACES),
56+
'WORKBOX_CDN_ROOT_URL': '/__WORKBOX/buildFile',
57+
}),
58+
],
59+
// Fail in the case of warning, so rebuilds work.
60+
onwarn({loc, message}) {
61+
if (loc) {
62+
message = `${loc.file} (${loc.line}:${loc.column}) ${message}`;
63+
}
64+
throw new Error(message);
65+
},
66+
cache: caches[env],
67+
});
6168

62-
const {output} = await bundle.generate({format: 'iife'});
69+
// Update the cache so subsequent bundles are faster, and make sure it
70+
// keep the dev/prod caches separate since the source files won't change
71+
// between those builds, but the outputs will.
72+
caches[env] = bundle.cache;
6373

64-
res.set('Content-Type', 'text/javascript');
65-
res.write(output[0].code);
66-
res.end();
74+
const {output} = await bundle.generate({format: 'iife'});
75+
76+
console.log(`Successfully built: ${req.url}`);
77+
res.send(output[0].code);
78+
} catch (error) {
79+
res.status(400).send('');
80+
console.error(error);
81+
}
6782
}
6883

6984
module.exports = {

infra/testing/server/routes/test-sw.js

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,26 @@ const match = '/test/:packageName/sw/';
1515

1616
async function handler(req, res) {
1717
const {packageName} = req.params;
18-
const testFiles = await globby(`test/${packageName}/sw/**/test-*.mjs`) || [];
18+
const testFilter = req.query.filter || '**/test-*.mjs';
19+
20+
const testFiles = await globby(`test/${packageName}/sw/${testFilter}`) || [];
1921
const testModules = testFiles.map((file) => '/' + file);
2022

21-
templateData.assign({packageName, testModules});
23+
if (testFiles.length > 0) {
24+
templateData.assign({packageName, testModules, testFilter});
2225

23-
res.set('Content-Type', 'text/html');
26+
res.set('Content-Type', 'text/html');
2427

25-
// Since templates can change between tests without the URL changing,
26-
// we need to make sure the browser doesn't cache the response.
27-
res.set('Cache-Control', 'no-cache, no-store, must-revalidate');
28-
res.set('Expires', '0');
28+
// Since templates can change between tests without the URL changing,
29+
// we need to make sure the browser doesn't cache the response.
30+
res.set('Cache-Control', 'no-cache, no-store, must-revalidate');
31+
res.set('Expires', '0');
2932

30-
const file = path.join(__dirname, '..', 'templates', 'test-sw.html.njk');
31-
res.render(file, templateData.get());
33+
const file = path.join(__dirname, '..', 'templates', 'test-sw.html.njk');
34+
res.render(file, templateData.get());
35+
} else {
36+
res.status(404).send(`No test files found for: ${testFilter}`);
37+
}
3238
}
3339

3440
module.exports = {

infra/testing/server/routes/test-window.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,14 @@ const match = '/test/:packageName/window/';
1515

1616
async function handler(req, res) {
1717
const {packageName} = req.params;
18+
const testFilter = req.query.filter || '**/test-*.mjs';
19+
1820
const testFiles =
19-
await globby(`test/${packageName}/window/**/test-*.mjs`) || [];
21+
await globby(`test/${packageName}/window/**/${testFilter}`) || [];
2022

2123
const testModules = testFiles.map((file) => '/' + file);
2224

23-
templateData.assign({packageName, testModules});
25+
templateData.assign({packageName, testModules, testFilter});
2426

2527
res.set('Content-Type', 'text/html');
2628

infra/testing/server/templates/test-sw-runner.js.njk

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ importScripts(
1212
'/node_modules/sinon/pkg/sinon-no-sourcemaps.js'
1313
);
1414

15+
// Disable workbox logs in test mode.
16+
self.__WB_DISABLE_DEV_LOGS = true;
17+
1518
self.expect = chai.expect;
1619

1720
// TODO(philipwalton): Move these globals back into imports once the
@@ -111,4 +114,4 @@ addEventListener('install', (event) => {
111114
event.waitUntil(testsComplete);
112115
}, {once: true}); // Run once since `install` events are dispatched in tests.
113116

114-
importScripts('sw-bundle.js');
117+
importScripts('sw-bundle.js?filter={{ testFilter }}');

0 commit comments

Comments
 (0)