blob: ab5329b29aa636bd5b04fd418c82c3f76f65f230 [file] [log] [blame]
# Copyright 2017 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"Unit testing in a browser"
load("@io_bazel_rules_webtesting//web/internal:constants.bzl", "DEFAULT_WRAPPED_TEST_TAGS")
load("@io_bazel_rules_webtesting//web:web.bzl", "web_test_suite")
load(":karma_web_test.bzl", "KARMA_GENERIC_WEB_TEST_ATTRS", "run_karma_web_test")
# Using generic karma_web_test attributes under the hood
TS_WEB_TEST_ATTRS = dict(KARMA_GENERIC_WEB_TEST_ATTRS, **{})
def _ts_web_test_impl(ctx):
# Using karma_web_test under the hood
runfiles = run_karma_web_test(ctx)
return [DefaultInfo(
files = depset([ctx.outputs.executable]),
runfiles = runfiles,
executable = ctx.outputs.executable,
)]
_ts_web_test = rule(
implementation = _ts_web_test_impl,
test = True,
executable = True,
attrs = TS_WEB_TEST_ATTRS,
)
def ts_web_test(
srcs = [],
deps = [],
data = [],
configuration_env_vars = [],
bootstrap = [],
runtime_deps = [],
static_files = [],
tags = [],
**kwargs):
"""Runs unit tests in a browser.
When executed under `bazel test`, this uses a headless browser for speed.
This is also because `bazel test` allows multiple targets to be tested together,
and we don't want to open a Chrome window on your machine for each one. Also,
under `bazel test` the test will execute and immediately terminate.
Running under `ibazel test` gives you a "watch mode" for your tests. The rule is
optimized for this case - the test runner server will stay running and just
re-serve the up-to-date JavaScript source bundle.
To debug a single test target, run it with `bazel run` instead. This will open a
browser window on your computer. Also you can use any other browser by opening
the URL printed when the test starts up. The test will remain running until you
cancel the `bazel run` command.
This rule will use your system Chrome. Your environment must specify CHROME_BIN
so that the rule will know which Chrome binary to run.
Currently this rule uses Karma as the test runner under the hood, but this is
an implementation detail. We might switch to another runner like Jest in the future.
Args:
srcs: A list of JavaScript test files
deps: Other targets which produce JavaScript such as `ts_library`
data: Runtime dependencies
configuration_env_vars: Pass these configuration environment variables to the resulting binary.
Chooses a subset of the configuration environment variables (taken from ctx.var), which also
includes anything specified via the --define flag.
Note, this can lead to different outputs produced by this rule.
bootstrap: JavaScript files to include *before* the module loader (require.js).
For example, you can include Reflect,js for TypeScript decorator metadata reflection,
or UMD bundles for third-party libraries.
runtime_deps: Dependencies which should be loaded after the module loader but before the srcs and deps.
These should be a list of targets which produce JavaScript such as `ts_library`.
The files will be loaded in the same order they are declared by that rule.
static_files: Arbitrary files which are available to be served on request.
Files are served at:
`/base/<WORKSPACE_NAME>/<path-to-file>`, e.g.
`/base/npm_bazel_typescript/examples/testing/static_script.js`
tags: Standard Bazel tags, this macro adds tags for ibazel support as well as
`browser:chromium-system` to allow for filtering on systems with no
system Chrome.
**kwargs: Passed through to `ts_web_test`
"""
_ts_web_test(
srcs = srcs,
deps = deps,
data = data,
configuration_env_vars = configuration_env_vars,
bootstrap = bootstrap,
runtime_deps = runtime_deps,
static_files = static_files,
tags = tags + [
# Users don't need to know that this tag is required to run under ibazel
"ibazel_notify_changes",
# Always attach this label to allow filtering, eg. envs w/ no browser
"browser:chromium-system",
],
**kwargs
)
def ts_web_test_suite(
name,
browsers = ["@io_bazel_rules_webtesting//browsers:chromium-local"],
args = None,
browser_overrides = None,
config = None,
flaky = None,
local = None,
shard_count = None,
size = None,
tags = [],
test_suite_tags = None,
timeout = None,
visibility = None,
web_test_data = [],
wrapped_test_tags = None,
**remaining_keyword_args):
"""Defines a test_suite of web_test targets that wrap a ts_web_test target.
This macro also accepts all parameters in ts_web_test. See ts_web_test docs for
details.
Args:
name: The base name of the test.
browsers: A sequence of labels specifying the browsers to use.
args: Args for web_test targets generated by this extension.
browser_overrides: Dictionary; optional; default is an empty dictionary. A
dictionary mapping from browser names to browser-specific web_test
attributes, such as shard_count, flakiness, timeout, etc. For example:
{'//browsers:chrome-native': {'shard_count': 3, 'flaky': 1}
'//browsers:firefox-native': {'shard_count': 1, 'timeout': 100}}.
config: Label; optional; Configuration of web test features.
flaky: A boolean specifying that the test is flaky. If set, the test will
be retried up to 3 times (default: 0)
local: boolean; optional.
shard_count: The number of test shards to use per browser. (default: 1)
size: A string specifying the test size. (default: 'large')
tags: A list of test tag strings to apply to each generated web_test_suite target.
This macro adds a couple for ibazel.
test_suite_tags: A list of tag strings for the generated test_suite.
timeout: A string specifying the test timeout (default: computed from size)
visibility: List of labels; optional.
web_test_data: Data dependencies for the web_test_suite.
wrapped_test_tags: A list of test tag strings to use for the wrapped test
**remaining_keyword_args: Arguments for the wrapped test target.
"""
# Check explicitly for None so that users can set this to the empty list
if wrapped_test_tags == None:
wrapped_test_tags = DEFAULT_WRAPPED_TEST_TAGS
size = size or "large"
wrapped_test_name = name + "_wrapped_test"
_ts_web_test(
name = wrapped_test_name,
args = args,
flaky = flaky,
local = local,
shard_count = shard_count,
size = size,
tags = wrapped_test_tags,
timeout = timeout,
visibility = ["//visibility:private"],
**remaining_keyword_args
)
web_test_suite(
name = name,
launcher = ":" + wrapped_test_name,
args = args,
browsers = browsers,
browser_overrides = browser_overrides,
config = config,
data = web_test_data,
flaky = flaky,
local = local,
shard_count = shard_count,
size = size,
tags = tags + [
# Users don't need to know that this tag is required to run under ibazel
"ibazel_notify_changes",
],
test = wrapped_test_name,
test_suite_tags = test_suite_tags,
timeout = timeout,
visibility = visibility,
)