blob: 78ff751c8c190a8776d088b8c0186a2200f1d059 [file] [log] [blame]
"""This module defines the karma_test rule."""
load("@npm//karma:index.bzl", _generated_karma_test = "karma_test")
load("//infra-sk/esbuild:esbuild.bzl", "esbuild_dev_bundle")
load("//infra-sk:ts_library.bzl", "ts_library")
def karma_test(
name,
src,
deps = [],
karma_config_file = "//infra-sk/karma_test:karma.conf.js",
static_karma_files = []):
"""Runs TypeScript unit tests in a browser with Karma, using Mocha as the test runner.
When invoked via `bazel test`, a headless Chrome browser will be used. This supports testing
multiple karma_test targets in parallel, and works on RBE.
When invoked via `bazel run`, it prints out a URL to stdout that can be opened in the browser,
e.g. to debug the tests using the browser's developer tools. Source maps are generated.
When invoked via `ibazel test`, the test runner never exits, and tests will be rerun every time
a source file is changed.
When invoked via `ibazel run`, it will act the same way as `bazel run`, but the tests will be
rebuilt automatically when a source file changes. Reload the browser page to see the changes.
Args:
name: The name of the target.
src: A single TypeScript source file.
deps: Any ts_library dependencies.
karma_config_file: A string that refers to the karma.conf.js file which should be used to run
the test. If omitted, a sensible default is used.
static_karma_files: A list of labels for additional files that should be made available to
be served statically for karma tests. If this is provided, a custom karma_config_file
should also be supplied to make use of the absolute file paths which are appended to the
karma "start" command.
"""
# Enforce test naming conventions. The Gazelle extension for front-end code relies on these.
if not src.endswith("_test.ts"):
fail("Karma tests must end with \"_test.ts\".")
for suffix in ["_puppeteer_test.ts", "_nodejs_test.ts"]:
if src.endswith(suffix):
fail("Karma tests cannot end with \"%s\"." % suffix)
ts_library(
name = name + "_lib",
srcs = [src],
deps = deps,
)
esbuild_dev_bundle(
name = name + "_bundle",
entry_point = src,
deps = [name + "_lib"],
output = name + "_bundle.js",
)
static_template_args = []
for f in static_karma_files:
# Include absolute file paths to the static karma files
static_template_args.append("$$(rlocation $(location %s))" % f)
# This rule is automatically generated by rules_nodejs from Karma's package.json file.
_generated_karma_test(
name = name,
size = "large",
data = [
name + "_bundle.js",
karma_config_file,
"@npm//karma-chrome-launcher",
"@npm//karma-sinon",
"@npm//karma-mocha",
"@npm//karma-chai",
"@npm//karma-chai-dom",
"@npm//karma-spec-reporter",
"@npm//mocha",
"@google_chrome//:all_files", # Provides Google Chrome, libraries and fonts.
] + static_karma_files,
templated_args = [
"start",
"$(execpath %s)" % karma_config_file,
# This gets the absolute file path to the JS bundle created by esbuild.
"$$(rlocation $(location %s_bundle.js))" % name,
] + static_template_args,
tags = [
# Necessary for it to work with ibazel.
"ibazel_notify_changes",
],
)