Skip to content

Commit e8b2e3f

Browse files
crisbetotinayuangao
authored andcommitted
build: add karma task for easier cross-browser debugging (#7796)
Adds the `gulp test:static` task that is identical to `gulp test`, however it doesn't launch Chrome automatically, which is convenient for debugging any browser that isn't Chrome. Currently the debugging flow for other browsers is running the Gulp task which launches Chrome, waiting for it to finish running the tests, connect the other browser, wait for the new browser to finish and then start debugging. With the new task you can just run the Gulp task and connect and disconnect only the relevant browsers.
1 parent 288c243 commit e8b2e3f

File tree

1 file changed

+48
-34
lines changed

1 file changed

+48
-34
lines changed

tools/gulp/tasks/unit-test.ts

Lines changed: 48 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,12 @@ import {buildConfig, sequenceTask} from 'material2-build-tools';
55
// There are no type definitions available for these imports.
66
const runSequence = require('run-sequence');
77

8-
const {packagesDir, projectDir} = buildConfig;
8+
// Default Karma options.
9+
const defaultOptions = {
10+
configFile: join(buildConfig.projectDir, 'test/karma.conf.js'),
11+
autoWatch: false,
12+
singleRun: false
13+
};
914

1015
/** Builds everything that is necessary for karma. */
1116
task(':test:build', sequenceTask(
@@ -23,10 +28,7 @@ task('test:single-run', [':test:build'], (done: () => void) => {
2328
// Load karma not outside. Karma pollutes Promise with a different implementation.
2429
const karma = require('karma');
2530

26-
new karma.Server({
27-
configFile: join(projectDir, 'test/karma.conf.js'),
28-
singleRun: true
29-
}, (exitCode: number) => {
31+
new karma.Server({...defaultOptions, singleRun: true}, (exitCode: number) => {
3032
// Immediately exit the process if Karma reported errors, because due to
3133
// potential still running tunnel-browsers gulp won't exit properly.
3234
exitCode === 0 ? done() : process.exit(exitCode);
@@ -35,39 +37,51 @@ task('test:single-run', [':test:build'], (done: () => void) => {
3537

3638
/**
3739
* [Watch task] Runs the unit tests, rebuilding and re-testing when sources change.
38-
* Does not inline resources. Note that this doesn't use Karma's built-in file
39-
* watching. Due to the way our build process is set up, Karma ends up firing
40-
* it's change detection for every file that is written to disk, which causes
41-
* it to run tests multiple time and makes it hard to follow the console output.
42-
* This approach runs the Karma server and then depends on the Gulp API to tell
43-
* Karma when to run the tests.
40+
* Does not inline resources.
4441
*
4542
* This task should be used when running unit tests locally.
4643
*/
47-
task('test', [':test:build'], () => {
48-
const patternRoot = join(packagesDir, '**/*');
49-
// Load karma not outside. Karma pollutes Promise with a different implementation.
50-
const karma = require('karma');
44+
task('test', [':test:build'], karmaWatchTask());
5145

52-
// Configure the Karma server and override the autoWatch and singleRun just in case.
53-
const server = new karma.Server({
54-
configFile: join(projectDir, 'test/karma.conf.js'),
55-
autoWatch: false,
56-
singleRun: false
57-
});
46+
/**
47+
* Runs a Karma server which will run the unit tests against any browser that connects to it.
48+
* This is identical to `gulp test`, however it won't launch and manage Chrome automatically,
49+
* which makes it convenient debugging unit tests against multiple different browsers.
50+
*/
51+
task('test:static', [':test:build'], karmaWatchTask({browsers: []}));
5852

59-
// Refreshes Karma's file list and schedules a test run.
60-
// Tests will only run if TypeScript compilation was successful.
61-
const runTests = (err?: Error) => {
62-
if (!err) {
63-
server.refreshFiles().then(() => server._injector.get('executor').schedule());
64-
}
65-
};
53+
/**
54+
* Returns a Gulp task that spawns a Karma server and reloads whenever the files change.
55+
* Note that this doesn't use Karma's built-in file watching. Due to the way our build
56+
* process is set up, Karma ends up firing it's change detection for every file that is
57+
* written to disk, which causes it to run tests multiple time and makes it hard to follow
58+
* the console output. This approach runs the Karma server and then depends on the Gulp API
59+
* to tell Karma when to run the tests.
60+
* @param overrides Karma options to use on top of the defaults.
61+
*/
62+
function karmaWatchTask(options?: any) {
63+
return () => {
64+
const patternRoot = join(buildConfig.packagesDir, '**/*');
65+
// Note: Karma shouldn't be required from the outside, because it
66+
// pollutes the global Promise with a custom implementation.
67+
const karma = require('karma');
6668

67-
// Boot up the test server and run the tests whenever a new browser connects.
68-
server.start();
69-
server.on('browser_register', () => runTests());
69+
// Configure the Karma server and override the autoWatch and singleRun just in case.
70+
const server = new karma.Server({...defaultOptions, ...options});
7071

71-
// Whenever a file change has been recognized, rebuild and re-run the tests.
72-
watch(patternRoot + '.+(ts|scss|html)', () => runSequence(':test:build', runTests));
73-
});
72+
// Refreshes Karma's file list and schedules a test run.
73+
// Tests will only run if TypeScript compilation was successful.
74+
const runTests = (error?: Error) => {
75+
if (!error) {
76+
server.refreshFiles().then(() => server._injector.get('executor').schedule());
77+
}
78+
};
79+
80+
// Boot up the test server and run the tests whenever a new browser connects.
81+
server.start();
82+
server.on('browser_register', () => runTests());
83+
84+
// Whenever a file change has been recognized, rebuild and re-run the tests.
85+
watch(patternRoot + '.+(ts|scss|html)', () => runSequence(':test:build', runTests));
86+
};
87+
}

0 commit comments

Comments
 (0)