Skip to content

Commit 0b49122

Browse files
Run Karma Chrome tests headlessly (#6997)
Avoid opening a bunch of browser pages when running karma chrome tests where possible. This excludes WebGPU on Linux because headless webgpu is not supported on linux yet. Add the flag `--//:headless=true|false` (default true) to control this and set it to false on Windows.
1 parent a234798 commit 0b49122

File tree

5 files changed

+74
-13
lines changed

5 files changed

+74
-13
lines changed

.bazelrc

+3-2
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,12 @@ build --action_env=BROWSERSTACK_USERNAME --action_env=BROWSERSTACK_KEY
6868
run --action_env=BROWSERSTACK_USERNAME --action_env=BROWSERSTACK_KEY
6969
test --action_env=BROWSERSTACK_USERNAME --action_env=BROWSERSTACK_KEY
7070

71-
# Platform specific DISPLAY environment variable for webgl
71+
# Platform specific DISPLAY environment variable for webgl and headless setting
72+
# for browser tests.
7273
test --enable_platform_specific_config
7374
test:linux --test_env=DISPLAY
7475
test:macos --define DISPLAY=true
75-
test:windows --define DISPLAY=true
76+
test:windows --define DISPLAY=true --//:headless=false
7677

7778
# Enable debugging tests with --config=debug
7879
run:debug --test_arg=--node_options=--inspect-brk --test_output=streamed --test_strategy=exclusive --test_timeout=9999 --nocache_test_results

BUILD.bazel

+7-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
# =============================================================================
1515

1616
load("@npm//@bazel/concatjs:index.bzl", "ts_config")
17-
load("//tools:tfjs_web_test.bzl", "grep_flag")
17+
load("//tools:tfjs_web_test.bzl", "grep_flag", "headless_flag")
1818

1919
package(default_visibility = ["//visibility:public"])
2020

@@ -42,6 +42,12 @@ grep_flag(
4242
visibility = ["//visibility:public"],
4343
)
4444

45+
headless_flag(
46+
name = "headless",
47+
build_setting_default = True,
48+
visibility = ["//visibility:public"],
49+
)
50+
4551
test_suite(
4652
name = "tests",
4753
tests = [

DEVELOPMENT.md

+12-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ $ yarn test --//:grep=multinomial
6767
> Chrome 62.0.3202 (Mac OS X 10.12.6): Executed 28 of 1891 (skipped 1863) SUCCESS (6.914 secs / 0.634 secs)
6868
```
6969

70-
By default, the tests run once and exit. To keep the browser window open, run the following:
70+
By default, the tests run once and exit. To keep the karma server active, run the following:
7171

7272
```bash
7373
# For packages with only browser tests
@@ -76,6 +76,17 @@ $ yarn test-debug
7676
$ yarn test-browser-debug
7777
```
7878

79+
You can now connect to the server with your own browser.
80+
81+
On most platforms, Karma tests will run with a headless Chrome browser. This can be overridden by setting the
82+
`--//:headless` flag.
83+
84+
```bash
85+
# Run tests with a visible browser window. Note this does not work well with
86+
# 'watch' modes such as 'test-dev' or 'ibazel'.
87+
$ yarn test --//:headless=false
88+
```
89+
7990
#### Packaging (browser and npm)
8091

8192
In any of the directories the following commands build the NPM tarball:

tools/karma_template.conf.js

+29-9
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ const browserstackConfig = {
2020
port: 9876,
2121
};
2222

23+
// Select Chrome or ChromeHeadless based on the value of the --//:headless flag.
24+
const CHROME = TEMPLATE_headless ? 'ChromeHeadless' : 'Chrome';
25+
2326
const CUSTOM_LAUNCHERS = {
2427
// For browserstack configs see:
2528
// https://www.browserstack.com/automate/node
@@ -66,21 +69,28 @@ const CUSTOM_LAUNCHERS = {
6669
os_version: '10'
6770
},
6871
chrome_with_swift_shader: {
69-
base: 'Chrome',
72+
base: CHROME,
7073
flags: ['--blacklist-accelerated-compositing', '--blacklist-webgl']
7174
},
7275
chrome_autoplay: {
73-
base: 'Chrome',
74-
flags: ['--autoplay-policy=no-user-gesture-required'],
76+
base: CHROME,
77+
flags: [
78+
'--autoplay-policy=no-user-gesture-required',
79+
'--no-sandbox',
80+
],
7581
},
7682
chrome_webgpu_linux: {
7783
base: 'ChromeCanary',
7884
flags: [
79-
'--disable-dawn-features=disallow_unsafe_apis',
80-
'--flag-switches-begin',
81-
'--enable-unsafe-webgpu',
85+
// See https://bugs.chromium.org/p/chromium/issues/detail?id=765284
8286
'--enable-features=Vulkan,UseSkiaRenderer',
83-
'--flag-switches-end',
87+
'--use-vulkan=native',
88+
'--enable-unsafe-webgpu',
89+
'--disable-vulkan-fallback-to-gl-for-testing',
90+
'--disable-vulkan-surface',
91+
'--disable-features=VaapiVideoDecoder',
92+
'--ignore-gpu-blocklist',
93+
'--use-angle=vulkan',
8494
]
8595
},
8696
chrome_webgpu: {
@@ -90,10 +100,17 @@ const CUSTOM_LAUNCHERS = {
90100
'--flag-switches-begin',
91101
'--enable-unsafe-webgpu',
92102
'--flag-switches-end',
103+
'--no-sandbox',
93104
]
94105
},
95-
chrome_debugging:
96-
{base: 'Chrome', flags: ['--remote-debugging-port=9333']}
106+
chrome_debugging: {
107+
base: 'Chrome',
108+
flags: ['--remote-debugging-port=9333'],
109+
},
110+
chrome_no_sandbox: {
111+
base: CHROME,
112+
flags: ['--no-sandbox'],
113+
}
97114
};
98115

99116
module.exports = function(config) {
@@ -106,6 +123,9 @@ module.exports = function(config) {
106123
throw new Error(`Missing launcher for ${browser}`);
107124
}
108125
extraConfig.browsers = [browser];
126+
} else {
127+
// Use no sandbox by default. This has better support on MacOS.
128+
extraConfig.browsers = ['chrome_no_sandbox'];
109129
}
110130
if (browserLauncher?.base === 'BrowserStack') {
111131
const username = process.env.BROWSERSTACK_USERNAME;

tools/tfjs_web_test.bzl

+23
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ PEER_DEPS = [
2929
"@npm//karma-jasmine-order-reporter",
3030
]
3131

32+
# @//:grep flag greps for a set of tests to run
3233
GrepProvider = provider(fields = ["grep"])
3334

3435
def _grep_flag_impl(ctx):
@@ -39,8 +40,20 @@ grep_flag = rule(
3940
build_setting = config.string(flag = True),
4041
)
4142

43+
# @//:headless flag runs tests headlessly. Defaults to true.
44+
HeadlessProvider = provider(fields = ["headless"])
45+
46+
def _headless_flag_impl(ctx):
47+
return HeadlessProvider(headless = ctx.build_setting_value)
48+
49+
headless_flag = rule(
50+
implementation = _headless_flag_impl,
51+
build_setting = config.bool(flag = True),
52+
)
53+
4254
def _make_karma_config_impl(ctx):
4355
grep = ctx.attr._grep[GrepProvider].grep
56+
headless = ctx.attr.headless[HeadlessProvider].headless
4457
output_file_path = ctx.label.name + ".js"
4558
output_file = ctx.actions.declare_file(output_file_path)
4659
args = ctx.attr.args
@@ -54,6 +67,7 @@ def _make_karma_config_impl(ctx):
5467
substitutions = {
5568
"TEMPLATE_args": str(args),
5669
"TEMPLATE_browser": ctx.attr.browser,
70+
"TEMPLATE_headless": "true" if headless else "false",
5771
"TEMPLATE_jasmine_random": "false" if seed else "true",
5872
"TEMPLATE_jasmine_seed": seed if seed else "undefined",
5973
},
@@ -74,6 +88,15 @@ _make_karma_config = rule(
7488
default = "",
7589
doc = "The browser to run",
7690
),
91+
"headless": attr.label(
92+
default = "@//:headless",
93+
doc = """Whether to run chrome tests headlessly.
94+
95+
Defaults to true on most platforms. Note that not all browsers
96+
support headless mode. Check //tools/karma_template.conf.js for
97+
more details.
98+
""",
99+
),
77100
"seed": attr.string(
78101
default = "",
79102
doc = """Use this seed for test order.

0 commit comments

Comments
 (0)