Add karma_web_test and karma_web_test_suite
Closes #363
PiperOrigin-RevId: 228963937
diff --git a/defs.bzl b/defs.bzl
index 3f4b0b3..4f68fa2 100644
--- a/defs.bzl
+++ b/defs.bzl
@@ -21,8 +21,13 @@
load("//:package.bzl", "VERSION")
load("//internal/devserver:ts_devserver.bzl", _ts_devserver = "ts_devserver_macro")
load(
+ "//internal/karma:karma_web_test.bzl",
+ _karma_web_test = "karma_web_test",
+ _karma_web_test_suite = "karma_web_test_suite",
+)
+load(
"//internal/karma:ts_web_test.bzl",
- _ts_web_test = "ts_web_test_macro",
+ _ts_web_test = "ts_web_test",
_ts_web_test_suite = "ts_web_test_suite",
)
load("//internal/protobufjs:ts_proto_library.bzl", _ts_proto_library = "ts_proto_library")
@@ -38,6 +43,8 @@
# TODO(alexeagle): make ts_web_test && ts_web_test_suite work in google3
ts_web_test = _ts_web_test
ts_web_test_suite = _ts_web_test_suite
+karma_web_test = _karma_web_test
+karma_web_test_suite = _karma_web_test_suite
ts_proto_library = _ts_proto_library
# DO NOT ADD MORE rules here unless they appear in the generated docsite.
# Run yarn skydoc to re-generate the docsite.
diff --git a/examples/testing/BUILD.bazel b/examples/testing/BUILD.bazel
index ee484a9..d2d7e28 100644
--- a/examples/testing/BUILD.bazel
+++ b/examples/testing/BUILD.bazel
@@ -1,4 +1,4 @@
-load("//internal:defaults.bzl", "ts_library", "ts_web_test_suite")
+load("//internal:defaults.bzl", "karma_web_test_suite", "ts_library", "ts_web_test_suite")
ts_library(
name = "lib",
@@ -28,6 +28,40 @@
],
)
+karma_web_test_suite(
+ name = "testing_karma",
+ browsers = [
+ "@io_bazel_rules_webtesting//browsers:chromium-local",
+ "@io_bazel_rules_webtesting//browsers:firefox-local",
+ ],
+ config_file = ":karma.conf.js",
+ static_files = [
+ "static_script.js",
+ ],
+ runtime_deps = [
+ ":tests_setup",
+ ],
+ deps = [
+ ":tests",
+ "@npm//karma-json-result-reporter",
+ ],
+)
+
+karma_web_test_suite(
+ name = "testing_karma_sauce",
+ browsers = [
+ "@io_bazel_rules_webtesting//browsers/sauce:chrome-win10",
+ ],
+ tags = [
+ "sauce",
+ # TODO(alexeagle): enable on CI once we have set the SAUCE env variables
+ "manual",
+ ],
+ deps = [
+ ":tests",
+ ],
+)
+
ts_web_test_suite(
name = "testing",
browsers = [
diff --git a/examples/testing/karma.conf.js b/examples/testing/karma.conf.js
new file mode 100644
index 0000000..f96e698
--- /dev/null
+++ b/examples/testing/karma.conf.js
@@ -0,0 +1,12 @@
+module.exports = function(config) {
+ config.set({
+ plugins: ['karma-json-result-reporter'],
+ reporters: ['dots', 'progress', 'json-result'],
+ logLevel: config.LOG_DEBUG,
+ colors: false,
+ jsonResultReporter: {
+ outputFile: `${process.env['TEST_UNDECLARED_OUTPUTS_DIR']}/karma-result.json`,
+ isSynchronous: true,
+ },
+ });
+}
diff --git a/internal/defaults.bzl b/internal/defaults.bzl
index ba51502..ca2f423 100644
--- a/internal/defaults.bzl
+++ b/internal/defaults.bzl
@@ -14,7 +14,14 @@
"Defaults for rules_typescript repository not meant to be used downstream"
-load("@build_bazel_rules_typescript//:defs.bzl", _ts_library = "ts_library", _ts_web_test_suite = "ts_web_test_suite")
+load(
+ "@build_bazel_rules_typescript//:defs.bzl",
+ _karma_web_test = "karma_web_test",
+ _karma_web_test_suite = "karma_web_test_suite",
+ _ts_library = "ts_library",
+ _ts_web_test = "ts_web_test",
+ _ts_web_test_suite = "ts_web_test_suite",
+)
# We can't use the defaults for ts_library compiler and ts_web_test_suite karma
# internally because the defaults are .js dependencies on the npm packages that are
@@ -22,8 +29,17 @@
INTERNAL_TS_LIBRARY_COMPILER = "@build_bazel_rules_typescript//internal:tsc_wrapped_bin"
INTERNAL_KARMA_BIN = "@build_bazel_rules_typescript//internal/karma:karma_bin"
+def karma_web_test(karma = INTERNAL_KARMA_BIN, **kwargs):
+ _karma_web_test(karma = karma, **kwargs)
+
+def karma_web_test_suite(karma = INTERNAL_KARMA_BIN, **kwargs):
+ _karma_web_test_suite(karma = karma, **kwargs)
+
def ts_library(compiler = INTERNAL_TS_LIBRARY_COMPILER, **kwargs):
_ts_library(compiler = compiler, **kwargs)
+def ts_web_test(karma = INTERNAL_KARMA_BIN, **kwargs):
+ _ts_web_test(karma = karma, **kwargs)
+
def ts_web_test_suite(karma = INTERNAL_KARMA_BIN, **kwargs):
_ts_web_test_suite(karma = karma, **kwargs)
diff --git a/internal/karma/karma.conf.js b/internal/karma/karma.conf.js
index 70dc9bf..1ef2a49 100644
--- a/internal/karma/karma.conf.js
+++ b/internal/karma/karma.conf.js
@@ -7,8 +7,21 @@
const tmp = require('tmp');
const child_process = require('child_process');
- // Helper function to find a particular namedFile
- // within the webTestMetadata webTestFiles
+ const DEBUG = false;
+
+ TMPL_env_vars
+
+ const configPath = 'TMPL_config_file';
+
+ if (DEBUG)
+ console.info(`Karma test starting with:
+ cwd: ${process.cwd()}
+ configPath: ${configPath}`);
+
+ /**
+ * Helper function to find a particular namedFile
+ * within the webTestMetadata webTestFiles
+ */
function findNamedFile(webTestMetadata, key) {
let result;
webTestMetadata['webTestFiles'].forEach(entry => {
@@ -20,8 +33,10 @@
return result;
}
- // Helper function to extract a browser archive
- // and return the path to extract executable
+ /**
+ * Helper function to extract a browser archive
+ * and return the path to extract executable
+ */
function extractWebArchive(extractExe, archiveFile, executablePath) {
try {
// Paths are relative to the root runfiles folder
@@ -34,6 +49,7 @@
child_process.execFileSync(
extractExe, [archiveFile, '.'],
{stdio: [process.stdin, process.stdout, process.stderr]});
+ if (DEBUG) console.info(`Extracting web archive ${archiveFile} with ${extractExe} to ${extractedExecutablePath}`);
return extractedExecutablePath;
} catch (e) {
console.error(`Failed to extract ${archiveFile}`);
@@ -41,17 +57,19 @@
}
}
- // Chrome on Linux uses sandboxing, which needs user namespaces to be enabled.
- // This is not available on all kernels and it might be turned off even if it is available.
- // Notable examples where user namespaces are not available include:
- // - In Debian it is compiled-in but disabled by default.
- // - The Docker daemon for Windows or OSX does not support user namespaces.
- // We can detect if user namespaces are supported via /proc/sys/kernel/unprivileged_userns_clone.
- // For more information see:
- // https://github.com/Googlechrome/puppeteer/issues/290
- // https://superuser.com/questions/1094597/enable-user-namespaces-in-debian-kernel#1122977
- // https://github.com/karma-runner/karma-chrome-launcher/issues/158
- // https://github.com/angular/angular/pull/24906
+ /**
+ * Chrome on Linux uses sandboxing, which needs user namespaces to be enabled.
+ * This is not available on all kernels and it might be turned off even if it is available.
+ * Notable examples where user namespaces are not available include:
+ * - In Debian it is compiled-in but disabled by default.
+ * - The Docker daemon for Windows or OSX does not support user namespaces.
+ * We can detect if user namespaces are supported via /proc/sys/kernel/unprivileged_userns_clone.
+ * For more information see:
+ * https://github.com/Googlechrome/puppeteer/issues/290
+ * https://superuser.com/questions/1094597/enable-user-namespaces-in-debian-kernel#1122977
+ * https://github.com/karma-runner/karma-chrome-launcher/issues/158
+ * https://github.com/angular/angular/pull/24906
+ */
function supportsSandboxing() {
if (process.platform !== 'linux') {
return true;
@@ -65,14 +83,177 @@
return false;
}
- const browsers = [];
- let customLaunchers = null;
+ /**
+ * Helper function to override base karma config values.
+ */
+ function overrideConfigValue(conf, name, value) {
+ if (conf.hasOwnProperty(name)) {
+ console.warn(
+ `Your karma configuration specifies '${name}' which will be overwritten by Bazel`);
+ }
+ conf[name] = value;
+ }
- // WEB_TEST_METADATA is configured in rules_webtesting based on value
- // of the browsers attribute passed to ts_web_test_suite
- // We setup the karma configuration based on the values in this object
- if (process.env['WEB_TEST_METADATA']) {
+ /**
+ * Helper function to merge base karma config values that are arrays.
+ */
+ function mergeConfigArray(conf, name, values) {
+ if (!conf[name]) {
+ conf[name] = [];
+ }
+ values.forEach(v => {
+ if (!conf[name].includes(v)) {
+ conf[name].push(v);
+ }
+ })
+ }
+
+ /**
+ * Configuration settings for karma under Bazel common to karma_web_test
+ * and karma_web_test_suite.
+ */
+ function configureBazelConfig(config, conf) {
+ // list of karma plugins
+ mergeConfigArray(conf, 'plugins', [
+ 'karma-*',
+ '@bazel/karma',
+ 'karma-sourcemap-loader',
+ 'karma-chrome-launcher',
+ 'karma-firefox-launcher',
+ 'karma-sauce-launcher',
+ ]);
+
+ // list of karma preprocessors
+ if (!conf.preprocessors) {
+ conf.preprocessors = {}
+ }
+ conf.preprocessors['**/*.js'] = ['sourcemap'];
+
+ // list of test frameworks to use
+ overrideConfigValue(conf, 'frameworks', ['jasmine', 'concat_js']);
+
+ // test results reporter to use
+ // possible values: 'dots', 'progress'
+ // available reporters: https://npmjs.org/browse/keyword/karma-reporter
+ mergeConfigArray(conf, 'reporters', ['progress']);
+
+ // enable / disable colors in the output (reporters and logs)
+ if (!conf.colors) {
+ conf.colors = true;
+ }
+
+ // level of logging
+ // possible values: config.LOG_DISABLE || config.LOG_ERROR ||
+ // config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
+ if (!conf.logLevel) {
+ conf.logLevel = config.LOG_INFO;
+ }
+
+ // enable / disable watching file and executing tests whenever
+ // any file changes
+ overrideConfigValue(conf, 'autoWatch', true);
+
+ // Continuous Integration mode
+ // if true, Karma captures browsers, runs the tests and exits
+ // note: run_karma.sh may override this as a command-line option.
+ overrideConfigValue(conf, 'singleRun', false);
+
+ // Concurrency level
+ // how many browser should be started simultaneous
+ overrideConfigValue(conf, 'concurrency', Infinity);
+
+ // base path that will be used to resolve all patterns
+ // (eg. files, exclude)
+ overrideConfigValue(conf, 'basePath', 'TMPL_runfiles_path');
+
+ if (process.env['IBAZEL_NOTIFY_CHANGES'] === 'y') {
+ // Tell karma to only listen for ibazel messages on stdin rather than
+ // watch all the input files This is from fork alexeagle/karma in the
+ // ibazel branch:
+ // https://github.com/alexeagle/karma/blob/576d262af50b10e63485b86aee99c5358958c4dd/lib/server.js#L172
+ overrideConfigValue(conf, 'watchMode', 'ibazel');
+ }
+ }
+
+ /**
+ * Configure the 'files' and 'proxies' configuration attributes.
+ * These are concatenated into a single file by karma-concat-js.
+ */
+ function configureFiles(conf) {
+ overrideConfigValue(conf, 'files', [
+ TMPL_bootstrap_files
+ TMPL_user_files
+ ].map(f => {
+ if (f.startsWith('NODE_MODULES/')) {
+ try {
+ // attempt to resolve in @bazel/karma nested node_modules first
+ return require.resolve(f.replace(/^NODE_MODULES\//, '@bazel/karma/node_modules/'));
+ } catch (e) {
+ // if that failed then attempt to resolve in root node_modules
+ return require.resolve(f.replace(/^NODE_MODULES\//, ''));
+ }
+ } else {
+ return require.resolve(f);
+ }
+ }));
+ overrideConfigValue(conf, 'exclude', []);
+ overrideConfigValue(conf, 'proxies', {});
+
+ // static files are added to the files array but
+ // configured to not be included so karma-concat-js does
+ // not included them in the bundle
+ [TMPL_static_files].forEach((f) => {
+ // In Windows, the runfile will probably not be symlinked. Se we need to
+ // serve the real file through karma, and proxy calls to the expected file
+ // location in the runfiles to the real file.
+ const resolvedFile = require.resolve(f);
+ conf.files.push({pattern: resolvedFile, included: false});
+ // Prefixing the proxy path with '/absolute' allows karma to load local
+ // files. This doesn't see to be an official API.
+ // https://github.com/karma-runner/karma/issues/2703
+ conf.proxies['/base/' + f] = '/absolute' + resolvedFile;
+ });
+
+ var requireConfigContent = `
+// A simplified version of Karma's requirejs.config.tpl.js for use with Karma under Bazel.
+// This does an explicit \`require\` on each test script in the files, otherwise nothing will be loaded.
+(function(){
+ var runtimeFiles = [TMPL_runtime_files].map(function(file) { return file.replace(/\\.js$/, ''); });
+ var allFiles = [TMPL_user_files];
+ var allTestFiles = [];
+ allFiles.forEach(function (file) {
+ if (/[^a-zA-Z0-9](spec|test)\\.js$/i.test(file) && !/\\/node_modules\\//.test(file)) {
+ allTestFiles.push(file.replace(/\\.js$/, ''))
+ }
+ });
+ require(runtimeFiles, function() { return require(allTestFiles, window.__karma__.start); });
+})();
+`;
+
+ const requireConfigFile = tmp.fileSync(
+ {keep: false, postfix: '.js', dir: process.env['TEST_TMPDIR']});
+ fs.writeFileSync(requireConfigFile.name, requireConfigContent);
+ conf.files.push(requireConfigFile.name);
+ }
+
+ /**
+ * Configure karma under karma_web_test_suite.
+ * `browsers` and `customLaunchers` are setup by Bazel.
+ */
+ function configureTsWebTestSuiteConfig(conf) {
+ // WEB_TEST_METADATA is configured in rules_webtesting based on value
+ // of the browsers attribute passed to karms_web_test_suite
+ // We setup the karma configuration based on the values in this object
+ if (!process.env['WEB_TEST_METADATA']) {
+ // This is a karma_web_test rule since there is no WEB_TEST_METADATA
+ return;
+ }
+
+ overrideConfigValue(conf, 'browsers', []);
+ overrideConfigValue(conf, 'customLaunchers', null);
+
const webTestMetadata = require(process.env['WEB_TEST_METADATA']);
+ if (DEBUG) console.info(`WEB_TEST_METADATA: ${JSON.stringify(webTestMetadata, null, 2)}`);
if (webTestMetadata['environment'] === 'sauce') {
// If a sauce labs browser is chosen for the test such as
// "@io_bazel_rules_webtesting//browsers/sauce:chrome-win10"
@@ -85,7 +266,7 @@
}
// 'capabilities' will specify the sauce labs configuration to use
const capabilities = webTestMetadata['capabilities'];
- customLaunchers = {
+ conf.customLaunchers = {
'sauce': {
base: 'SauceLabs',
browserName: capabilities['browserName'],
@@ -93,7 +274,7 @@
version: capabilities['version'],
}
};
- browsers.push('sauce');
+ conf.browsers.push('sauce');
} else if (webTestMetadata['environment'] === 'local') {
// When a local chrome or firefox browser is chosen such as
// "@io_bazel_rules_webtesting//browsers:chromium-local" or
@@ -115,15 +296,15 @@
const browser = process.env['DISPLAY'] ? 'Chrome' : 'ChromeHeadless';
if (!supportsSandboxing()) {
const launcher = 'CustomChromeWithoutSandbox';
- customLaunchers = {
+ conf.customLaunchers = {
[launcher]: {
base: browser,
flags: ['--no-sandbox']
}
};
- browsers.push(launcher);
+ conf.browsers.push(launcher);
} else {
- browsers.push(browser);
+ conf.browsers.push(browser);
}
}
if (webTestNamedFiles['FIREFOX']) {
@@ -134,165 +315,76 @@
} else {
process.env.FIREFOX_BIN = require.resolve(webTestNamedFiles['FIREFOX']);
}
- browsers.push(process.env['DISPLAY'] ? 'Firefox' : 'FirefoxHeadless');
+ conf.browsers.push(process.env['DISPLAY'] ? 'Firefox' : 'FirefoxHeadless');
}
});
} else {
- console.warn(`Unknown WEB_TEST_METADATA environment '${webTestMetadata['environment']}'`);
- }
- }
-
- // Fallback to using the system local chrome if no valid browsers have been
- // configured above
- if (!browsers.length) {
- console.warn('No browsers configured. Configuring Karma to use system Chrome.');
- browsers.push(process.env['DISPLAY'] ? 'Chrome': 'ChromeHeadless');
- }
-
- const proxies = {};
- const files = [
- TMPL_bootstrap_files
- TMPL_user_files
- ].map(f => {
- if (f.startsWith('NODE_MODULES/')) {
- try {
- // attempt to resolve in @bazel/karma nested node_modules first
- return require.resolve(f.replace(/^NODE_MODULES\//, '@bazel/karma/node_modules/'));
- } catch (e) {
- // if that failed then attempt to resolve in root node_modules
- return require.resolve(f.replace(/^NODE_MODULES\//, ''));
- }
- } else {
- return require.resolve(f);
- }
- });
-
- // static files are added to the files array but
- // configured to not be included so karma-concat-js does
- // not included them in the bundle
- [TMPL_static_files].forEach((f) => {
- // In Windows, the runfile will probably not be symlinked. Se we need to
- // serve the real file through karma, and proxy calls to the expected file
- // location in the runfiles to the real file.
- const resolvedFile = require.resolve(f);
- files.push({pattern: resolvedFile, included: false});
- // Prefixing the proxy path with '/absolute' allows karma to load local
- // files. This doesn't see to be an official API.
- // https://github.com/karma-runner/karma/issues/2703
- proxies['/base/' + f] = '/absolute' + resolvedFile;
- });
-
- var requireConfigContent = `
-// A simplified version of Karma's requirejs.config.tpl.js for use with Karma under Bazel.
-// This does an explicit \`require\` on each test script in the files, otherwise nothing will be loaded.
-(function(){
- var runtimeFiles = [TMPL_runtime_files].map(function(file) { return file.replace(/\\.js$/, ''); });
- var allFiles = [TMPL_user_files];
- var allTestFiles = [];
- allFiles.forEach(function (file) {
- if (/[^a-zA-Z0-9](spec|test)\\.js$/i.test(file) && !/\\/node_modules\\//.test(file)) {
- allTestFiles.push(file.replace(/\\.js$/, ''))
- }
- });
- require(runtimeFiles, function() { return require(allTestFiles, window.__karma__.start); });
-})();
-`;
-
- const requireConfigFile = tmp.fileSync(
- {keep: false, postfix: '.js', dir: process.env['TEST_TMPDIR']});
- fs.writeFileSync(requireConfigFile.name, requireConfigContent);
- files.push(requireConfigFile.name);
-
- module.exports = function(config) {
- const configuration = {
- // list of karma plugins
- plugins: [
- 'karma-*',
- '@bazel/karma',
- 'karma-sourcemap-loader',
- 'karma-chrome-launcher',
- 'karma-firefox-launcher',
- 'karma-sauce-launcher',
- ],
-
- // list of karma preprocessors
- preprocessors: {'**/*.js': ['sourcemap']},
-
- // list of test frameworks to use
- frameworks: ['jasmine', 'concat_js'],
-
- // test results reporter to use
- // possible values: 'dots', 'progress'
- // available reporters: https://npmjs.org/browse/keyword/karma-reporter
- reporters: ['progress'],
-
- // web server port
- port: 9876,
-
- // enable / disable colors in the output (reporters and logs)
- colors: true,
-
- // level of logging
- // possible values: config.LOG_DISABLE || config.LOG_ERROR ||
- // config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
- logLevel: config.LOG_INFO,
-
- // enable / disable watching file and executing tests whenever any file
- // changes
- autoWatch: true,
-
- // start these browsers
- // available browser launchers:
- // https://npmjs.org/browse/keyword/karma-launcher
- browsers: browsers,
-
- // Continuous Integration mode
- // if true, Karma captures browsers, runs the tests and exits
- // note: run_karma.sh may override this as a command-line option.
- singleRun: false,
-
- // Concurrency level
- // how many browser should be started simultaneous
- concurrency: Infinity,
-
- // base path that will be used to resolve all patterns (eg. files,
- // exclude)
- basePath: 'TMPL_runfiles_path',
-
- // list of files passed to karma; these are concatenated into a single
- // file by karma-concat-js
- files,
- proxies,
+ throw new Error(`Unknown WEB_TEST_METADATA environment '${webTestMetadata['environment']}'`);
}
- if (process.env['IBAZEL_NOTIFY_CHANGES'] === 'y') {
- // Tell karma to only listen for ibazel messages on stdin rather than
- // watch all the input files This is from fork alexeagle/karma in the
- // ibazel branch:
- // https://github.com/alexeagle/karma/blob/576d262af50b10e63485b86aee99c5358958c4dd/lib/server.js#L172
- configuration.watchMode = 'ibazel';
+ if (!conf.browsers.length) {
+ throw new Error('No browsers configured in web test suite');
}
// Extra configuration is needed for saucelabs
// See: https://github.com/karma-runner/karma-sauce-launcher
- if (customLaunchers) {
+ if (conf.customLaunchers) {
// set the test name for sauce labs to use
// TEST_BINARY is set by Bazel and contains the name of the test
- // target posfixed with the the browser name such as
+ // target postfixed with the browser name such as
// 'examples/testing/testing_sauce_chrome-win10' for the
// test target examples/testing:testing
- configuration.sauceLabs = {
- testName: process.env['TEST_BINARY'] || 'ts_web_test_suite'
- };
+ if (!conf.sauceLabs) {
+ conf.sauceLabs = {}
+ }
+ conf.sauceLabs.testName = process.env['TEST_BINARY'] || 'karma';
- // setup the custom launchers for saucelabs
- configuration.customLaunchers = customLaunchers;
+ // Try "websocket" for a faster transmission first. Fallback to "polling" if necessary.
+ overrideConfigValue(conf, 'transports', ['websocket', 'polling']);
// add the saucelabs reporter
- configuration.reporters.push('saucelabs');
+ mergeConfigArray(conf, 'reporters', ['saucelabs']);
+ }
+ }
+
+ function configureTsWebTestConfig(conf) {
+ if (process.env['WEB_TEST_METADATA']) {
+ // This is a karma_web_test_suite rule since there is a WEB_TEST_METADATA
+ return;
}
- config.set(configuration);
+ // Fallback to using the system local chrome if no valid browsers have been
+ // configured above
+ if (!conf.browsers || !conf.browsers.length) {
+ console.warn('No browsers configured. Configuring Karma to use system Chrome.');
+ conf.browsers = [process.env['DISPLAY'] ? 'Chrome': 'ChromeHeadless'];
+ }
+ }
+
+ module.exports = function(config) {
+ let conf = {};
+
+ // Import the user's base karma configuration if specified
+ if (configPath) {
+ const baseConf = require(configPath);
+ if (typeof baseConf !== 'function') {
+ throw new Error('Invalid base karma configuration. Expected config function to be exported.');
+ }
+ const originalSetConfig = config.set;
+ config.set = function(c) { conf = c; }
+ baseConf(config);
+ config.set = originalSetConfig;
+ if (DEBUG) console.info(`Base karma configuration: ${JSON.stringify(conf, null, 2)}`);
+ }
+
+ configureBazelConfig(config, conf);
+ configureFiles(conf);
+ configureTsWebTestSuiteConfig(conf);
+ configureTsWebTestConfig(conf);
+
+ if (DEBUG) console.info(`Karma configuration: ${JSON.stringify(conf, null, 2)}`);
+
+ config.set(conf);
}
} catch (e) {
console.error('Error in karma configuration', e.toString());
diff --git a/internal/karma/karma_web_test.bzl b/internal/karma/karma_web_test.bzl
new file mode 100644
index 0000000..f6be58f
--- /dev/null
+++ b/internal/karma/karma_web_test.bzl
@@ -0,0 +1,449 @@
+# 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 with Karma"
+
+load("@build_bazel_rules_nodejs//internal/js_library:js_library.bzl", "write_amd_names_shim")
+load(
+ "@build_bazel_rules_nodejs//internal:node.bzl",
+ "expand_path_into_runfiles",
+ "sources_aspect",
+)
+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(":web_test.bzl", "COMMON_WEB_TEST_ATTRS")
+
+_CONF_TMPL = "//internal/karma:karma.conf.js"
+_DEFAULT_KARMA_BIN = "@npm//@bazel/karma/bin:karma"
+
+# Attributes for karma_web_test that are shared with ts_web_test which
+# uses Karma under the hood
+KARMA_GENERIC_WEB_TEST_ATTRS = dict(COMMON_WEB_TEST_ATTRS, **{
+ "bootstrap": attr.label_list(
+ doc = """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.""",
+ allow_files = [".js"],
+ ),
+ "karma": attr.label(
+ doc = "karma binary label",
+ default = Label(_DEFAULT_KARMA_BIN),
+ executable = True,
+ cfg = "target",
+ allow_files = True,
+ ),
+ "static_files": attr.label_list(
+ doc = """Arbitrary files which are available to be served on request.
+ Files are served at:
+ `/base/<WORKSPACE_NAME>/<path-to-file>`, e.g.
+ `/base/build_bazel_rules_typescript/examples/testing/static_script.js`""",
+ allow_files = True,
+ ),
+ "runtime_deps": attr.label_list(
+ doc = """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.""",
+ allow_files = True,
+ aspects = [sources_aspect],
+ ),
+ "_conf_tmpl": attr.label(
+ default = Label(_CONF_TMPL),
+ allow_single_file = True,
+ ),
+})
+
+# Attributes for karma_web_test that are specific to karma_web_test
+KARMA_WEB_TEST_ATTRS = dict(KARMA_GENERIC_WEB_TEST_ATTRS, **{
+ "config_file": attr.label(
+ doc = """User supplied Karma configuration file. Bazel will override
+ certain attributes of this configuration file. Attributes that are
+ overridden will be outputted to the test log.""",
+ allow_single_file = True,
+ aspects = [sources_aspect],
+ ),
+})
+
+# Helper function to convert a short path to a path that is
+# found in the MANIFEST file.
+def _short_path_to_manifest_path(ctx, short_path):
+ if short_path.startswith("../"):
+ return short_path[3:]
+ else:
+ return ctx.workspace_name + "/" + short_path
+
+# Write the AMD names shim bootstrap file
+def _write_amd_names_shim(ctx):
+ amd_names_shim = ctx.actions.declare_file(
+ "_%s.amd_names_shim.js" % ctx.label.name,
+ sibling = ctx.outputs.executable,
+ )
+ write_amd_names_shim(ctx.actions, amd_names_shim, ctx.attr.bootstrap)
+ return amd_names_shim
+
+# Generates the karma configuration file for the rule
+def _write_karma_config(ctx, files, amd_names_shim):
+ configuration = ctx.actions.declare_file(
+ "%s.conf.js" % ctx.label.name,
+ sibling = ctx.outputs.executable,
+ )
+
+ config_file = ""
+ if hasattr(ctx.file, "config_file"):
+ config_file = ctx.file.config_file
+ if hasattr(ctx.attr.config_file, "typescript"):
+ config_file = ctx.attr.config_file.typescript.es5_sources.to_list()[0]
+
+ # The files in the bootstrap attribute come before the require.js support.
+ # Note that due to frameworks = ['jasmine'], a few scripts will come before
+ # the bootstrap entries:
+ # jasmine-core/lib/jasmine-core/jasmine.js
+ # karma-jasmine/lib/boot.js
+ # karma-jasmine/lib/adapter.js
+ # This is desired so that the bootstrap entries can patch jasmine, as zone.js does.
+ bootstrap_entries = [
+ expand_path_into_runfiles(ctx, f.short_path)
+ for f in ctx.files.bootstrap
+ ]
+
+ # Explicitly list the requirejs library files here, rather than use
+ # `frameworks: ['requirejs']`
+ # so that we control the script order, and the bootstrap files come before
+ # require.js.
+ # That allows bootstrap files to have anonymous AMD modules, or to do some
+ # polyfilling before test libraries load.
+ # See https://github.com/karma-runner/karma/issues/699
+ # `NODE_MODULES/` is a prefix recogized by karma.conf.js to allow
+ # for a priority require of nested `@bazel/karma/node_modules` before
+ # looking in root node_modules.
+ bootstrap_entries += [
+ "NODE_MODULES/requirejs/require.js",
+ "NODE_MODULES/karma-requirejs/lib/adapter.js",
+ "/".join([ctx.workspace_name, amd_names_shim.short_path]),
+ ]
+
+ # Next we load the "runtime_deps" which we expect to contain named AMD modules
+ # Thus they should come after the require.js script, but before any srcs or deps
+ runtime_files = []
+ for d in ctx.attr.runtime_deps:
+ if not hasattr(d, "typescript"):
+ # Workaround https://github.com/bazelbuild/rules_nodejs/issues/57
+ # We should allow any JS source as long as it yields something that
+ # can be loaded by require.js
+ fail("labels in runtime_deps must be created by ts_library")
+ for src in d.typescript.es5_sources.to_list():
+ runtime_files.append(expand_path_into_runfiles(ctx, src.short_path))
+
+ # Finally we load the user's srcs and deps
+ user_entries = [
+ expand_path_into_runfiles(ctx, f.short_path)
+ for f in files.to_list()
+ ]
+
+ # Expand static_files paths to runfiles for config
+ static_files = [
+ expand_path_into_runfiles(ctx, f.short_path)
+ for f in ctx.files.static_files
+ ]
+
+ # root-relative (runfiles) path to the directory containing karma.conf
+ config_segments = len(configuration.short_path.split("/"))
+
+ # configuration_env_vars are set using process.env()
+ env_vars = ""
+ for k in ctx.attr.configuration_env_vars:
+ if k in ctx.var.keys():
+ env_vars += "process.env[\"%s\"]=\"%s\";\n" % (k, ctx.var[k])
+
+ ctx.actions.expand_template(
+ output = configuration,
+ template = ctx.file._conf_tmpl,
+ substitutions = {
+ "TMPL_bootstrap_files": "\n".join([" '%s'," % e for e in bootstrap_entries]),
+ "TMPL_config_file": expand_path_into_runfiles(ctx, config_file.short_path) if config_file else "",
+ "TMPL_env_vars": env_vars,
+ "TMPL_runfiles_path": "/".join([".."] * config_segments),
+ "TMPL_runtime_files": "\n".join([" '%s'," % e for e in runtime_files]),
+ "TMPL_static_files": "\n".join([" '%s'," % e for e in static_files]),
+ "TMPL_user_files": "\n".join([" '%s'," % e for e in user_entries]),
+ },
+ )
+
+ return configuration
+
+def run_karma_web_test(ctx):
+ """Creates an action that can run karma.
+
+ This is also used by ts_web_test_rule.
+
+ Args:
+ ctx: Bazel rule execution context
+
+ Returns:
+ The runfiles for the generated action.
+ """
+ files = depset(ctx.files.srcs)
+ for d in ctx.attr.deps + ctx.attr.runtime_deps:
+ if hasattr(d, "node_sources"):
+ files = depset(transitive = [files, d.node_sources])
+ elif hasattr(d, "files"):
+ files = depset(transitive = [files, d.files])
+
+ amd_names_shim = _write_amd_names_shim(ctx)
+
+ configuration = _write_karma_config(ctx, files, amd_names_shim)
+
+ ctx.actions.write(
+ output = ctx.outputs.executable,
+ is_executable = True,
+ content = """#!/usr/bin/env bash
+# Immediately exit if any command fails.
+set -e
+
+if [ -e "$RUNFILES_MANIFEST_FILE" ]; then
+ while read line; do
+ declare -a PARTS=($line)
+ if [ "${{PARTS[0]}}" == "{TMPL_karma}" ]; then
+ readonly KARMA=${{PARTS[1]}}
+ elif [ "${{PARTS[0]}}" == "{TMPL_conf}" ]; then
+ readonly CONF=${{PARTS[1]}}
+ fi
+ done < $RUNFILES_MANIFEST_FILE
+else
+ readonly KARMA=../{TMPL_karma}
+ readonly CONF=../{TMPL_conf}
+fi
+
+export HOME=$(mktemp -d)
+
+# Print the karma version in the test log
+echo $($KARMA --version)
+
+ARGV=( "start" $CONF )
+
+# Detect that we are running as a test, by using well-known environment
+# variables. See go/test-encyclopedia
+# Note: in Bazel 0.14 and later, TEST_TMPDIR is set for both bazel test and bazel run
+# so we also check for the BUILD_WORKSPACE_DIRECTORY which is set only for bazel run
+if [[ ! -z "${{TEST_TMPDIR}}" && ! -n "${{BUILD_WORKSPACE_DIRECTORY}}" ]]; then
+ ARGV+=( "--single-run" )
+fi
+
+$KARMA ${{ARGV[@]}}
+""".format(
+ TMPL_workspace = ctx.workspace_name,
+ TMPL_karma = _short_path_to_manifest_path(ctx, ctx.executable.karma.short_path),
+ TMPL_conf = _short_path_to_manifest_path(ctx, configuration.short_path),
+ ),
+ )
+
+ config_sources = []
+ if hasattr(ctx.file, "config_file"):
+ if ctx.file.config_file:
+ config_sources = [ctx.file.config_file]
+ if hasattr(ctx.attr.config_file, "node_sources"):
+ config_sources = ctx.attr.config_file.node_sources.to_list()
+
+ runfiles = [
+ configuration,
+ amd_names_shim,
+ ]
+ runfiles += config_sources
+ runfiles += ctx.files.srcs
+ runfiles += ctx.files.deps
+ runfiles += ctx.files.runtime_deps
+ runfiles += ctx.files.bootstrap
+ runfiles += ctx.files.static_files
+
+ return ctx.runfiles(
+ files = runfiles,
+ transitive_files = files,
+ ).merge(ctx.attr.karma[DefaultInfo].data_runfiles)
+
+def _karma_web_test_impl(ctx):
+ runfiles = run_karma_web_test(ctx)
+
+ return [DefaultInfo(
+ files = depset([ctx.outputs.executable]),
+ runfiles = runfiles,
+ executable = ctx.outputs.executable,
+ )]
+
+_karma_web_test = rule(
+ implementation = _karma_web_test_impl,
+ test = True,
+ executable = True,
+ attrs = KARMA_WEB_TEST_ATTRS,
+)
+
+def karma_web_test(
+ srcs = [],
+ deps = [],
+ data = [],
+ configuration_env_vars = [],
+ bootstrap = [],
+ runtime_deps = [],
+ static_files = [],
+ config_file = None,
+ tags = [],
+ **kwargs):
+ """Runs unit tests in a browser with Karma.
+
+ 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 by default. In the default case, your
+ environment must specify CHROME_BIN so that the rule will know which Chrome binary to run.
+ Other `browsers` and `customLaunchers` may be set using the a base Karma configuration
+ specified in the `config_file` attribute.
+
+ 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/build_bazel_rules_typescript/examples/testing/static_script.js`
+ config_file: User supplied Karma configuration file. Bazel will override
+ certain attributes of this configuration file. Attributes that are
+ overridden will be outputted to the test log.
+ tags: Standard Bazel tags, this macro adds tags for ibazel support
+ **kwargs: Passed through to `karma_web_test`
+ """
+
+ _karma_web_test(
+ srcs = srcs,
+ deps = deps,
+ data = data,
+ configuration_env_vars = configuration_env_vars,
+ bootstrap = bootstrap,
+ runtime_deps = runtime_deps,
+ static_files = static_files,
+ config_file = config_file,
+ tags = tags + [
+ # Users don't need to know that this tag is required to run under ibazel
+ "ibazel_notify_changes",
+ ],
+ **kwargs
+ )
+
+def karma_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 karma_web_test target.
+
+ This macro also accepts all parameters in karma_web_test. See karma_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 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.
+ 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"
+
+ _karma_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,
+ )
diff --git a/internal/karma/package.json b/internal/karma/package.json
index c5bf6d9..9ffa9c0 100644
--- a/internal/karma/package.json
+++ b/internal/karma/package.json
@@ -19,7 +19,7 @@
"karma-chrome-launcher": "2.2.0",
"karma-firefox-launcher": "1.1.0",
"karma-jasmine": "1.1.1",
- "karma-sauce-launcher": "1.2.0",
+ "karma-sauce-launcher": "2.0.2",
"karma-sourcemap-loader": "0.3.7",
"karma-requirejs": "1.1.0",
"requirejs": "2.3.5",
diff --git a/internal/karma/ts_web_test.bzl b/internal/karma/ts_web_test.bzl
index bcdee11..9189076 100644
--- a/internal/karma/ts_web_test.bzl
+++ b/internal/karma/ts_web_test.bzl
@@ -11,279 +11,108 @@
# 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 with Karma"
+"Unit testing in a browser"
-load("@build_bazel_rules_nodejs//internal/js_library:js_library.bzl", "write_amd_names_shim")
-load(
- "@build_bazel_rules_nodejs//internal:node.bzl",
- "expand_path_into_runfiles",
- "sources_aspect",
-)
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")
-_CONF_TMPL = "//internal/karma:karma.conf.js"
-_DEFAULT_KARMA_BIN = "@npm//@bazel/karma/bin:karma"
-
-def _short_path_to_manifest_path(ctx, short_path):
- if short_path.startswith("../"):
- return short_path[3:]
- else:
- return ctx.workspace_name + "/" + short_path
+# 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):
- conf = ctx.actions.declare_file(
- "%s.conf.js" % ctx.label.name,
- sibling = ctx.outputs.executable,
- )
+ # Using karma_web_test under the hood
+ runfiles = run_karma_web_test(ctx)
- files = depset(ctx.files.srcs)
- for d in ctx.attr.deps + ctx.attr.runtime_deps:
- if hasattr(d, "node_sources"):
- files = depset(transitive = [files, d.node_sources])
- elif hasattr(d, "files"):
- files = depset(transitive = [files, d.files])
-
- # Write the AMD names shim bootstrap file
- amd_names_shim = ctx.actions.declare_file(
- "_%s.amd_names_shim.js" % ctx.label.name,
- sibling = ctx.outputs.executable,
- )
- write_amd_names_shim(ctx.actions, amd_names_shim, ctx.attr.bootstrap)
-
- # The files in the bootstrap attribute come before the require.js support.
- # Note that due to frameworks = ['jasmine'], a few scripts will come before
- # the bootstrap entries:
- # jasmine-core/lib/jasmine-core/jasmine.js
- # karma-jasmine/lib/boot.js
- # karma-jasmine/lib/adapter.js
- # This is desired so that the bootstrap entries can patch jasmine, as zone.js does.
- bootstrap_entries = [
- expand_path_into_runfiles(ctx, f.short_path)
- for f in ctx.files.bootstrap
- ]
-
- # Explicitly list the requirejs library files here, rather than use
- # `frameworks: ['requirejs']`
- # so that we control the script order, and the bootstrap files come before
- # require.js.
- # That allows bootstrap files to have anonymous AMD modules, or to do some
- # polyfilling before test libraries load.
- # See https://github.com/karma-runner/karma/issues/699
- # `NODE_MODULES/` is a prefix recogized by karma.conf.js to allow
- # for a priority require of nested `@bazel/karma/node_modules` before
- # looking in root node_modules.
- bootstrap_entries += [
- "NODE_MODULES/requirejs/require.js",
- "NODE_MODULES/karma-requirejs/lib/adapter.js",
- "/".join([ctx.workspace_name, amd_names_shim.short_path]),
- ]
-
- # Next we load the "runtime_deps" which we expect to contain named AMD modules
- # Thus they should come after the require.js script, but before any srcs or deps
- runtime_files = []
- for d in ctx.attr.runtime_deps:
- if not hasattr(d, "typescript"):
- # Workaround https://github.com/bazelbuild/rules_nodejs/issues/57
- # We should allow any JS source as long as it yields something that
- # can be loaded by require.js
- fail("labels in runtime_deps must be created by ts_library")
- for src in d.typescript.es5_sources.to_list():
- runtime_files.append(expand_path_into_runfiles(ctx, src.short_path))
-
- # Finally we load the user's srcs and deps
- user_entries = [
- expand_path_into_runfiles(ctx, f.short_path)
- for f in files.to_list()
- ]
- static_files = [
- expand_path_into_runfiles(ctx, f.short_path)
- for f in ctx.files.static_files
- ]
-
- # root-relative (runfiles) path to the directory containing karma.conf
- config_segments = len(conf.short_path.split("/"))
-
- ctx.actions.expand_template(
- output = conf,
- template = ctx.file._conf_tmpl,
- substitutions = {
- "TMPL_bootstrap_files": "\n".join([" '%s'," % e for e in bootstrap_entries]),
- "TMPL_runfiles_path": "/".join([".."] * config_segments),
- "TMPL_runtime_files": "\n".join([" '%s'," % e for e in runtime_files]),
- "TMPL_static_files": "\n".join([" '%s'," % e for e in static_files]),
- "TMPL_user_files": "\n".join([" '%s'," % e for e in user_entries]),
- "TMPL_workspace_name": ctx.workspace_name,
- },
- )
-
- karma_runfiles = [
- conf,
- amd_names_shim,
- ]
- karma_runfiles += ctx.files.srcs
- karma_runfiles += ctx.files.deps
- karma_runfiles += ctx.files.runtime_deps
- karma_runfiles += ctx.files.bootstrap
- karma_runfiles += ctx.files.static_files
-
- ctx.actions.write(
- output = ctx.outputs.executable,
- is_executable = True,
- content = """#!/usr/bin/env bash
-if [ -e "$RUNFILES_MANIFEST_FILE" ]; then
- while read line; do
- declare -a PARTS=($line)
- if [ "${{PARTS[0]}}" == "{TMPL_karma}" ]; then
- readonly KARMA=${{PARTS[1]}}
- elif [ "${{PARTS[0]}}" == "{TMPL_conf}" ]; then
- readonly CONF=${{PARTS[1]}}
- fi
- done < $RUNFILES_MANIFEST_FILE
-else
- readonly KARMA=../{TMPL_karma}
- readonly CONF=../{TMPL_conf}
-fi
-
-export HOME=$(mktemp -d)
-ARGV=( "start" $CONF )
-
-# Detect that we are running as a test, by using well-known environment
-# variables. See go/test-encyclopedia
-# Note: in Bazel 0.14 and later, TEST_TMPDIR is set for both bazel test and bazel run
-# so we also check for the BUILD_WORKSPACE_DIRECTORY which is set only for bazel run
-if [[ ! -z "${{TEST_TMPDIR}}" && ! -n "${{BUILD_WORKSPACE_DIRECTORY}}" ]]; then
- ARGV+=( "--single-run" )
-fi
-
-$KARMA ${{ARGV[@]}}
-""".format(
- TMPL_workspace = ctx.workspace_name,
- TMPL_karma = _short_path_to_manifest_path(ctx, ctx.executable.karma.short_path),
- TMPL_conf = _short_path_to_manifest_path(ctx, conf.short_path),
- ),
- )
return [DefaultInfo(
files = depset([ctx.outputs.executable]),
- runfiles = ctx.runfiles(
- files = karma_runfiles,
- transitive_files = files,
- # Propagate karma_bin and its runfiles
- collect_data = True,
- collect_default = True,
- ),
+ runfiles = runfiles,
executable = ctx.outputs.executable,
)]
-ts_web_test = rule(
+_ts_web_test = rule(
implementation = _ts_web_test_impl,
test = True,
executable = True,
- attrs = {
- "srcs": attr.label_list(
- doc = "JavaScript source files",
- allow_files = [".js"],
- ),
- "bootstrap": attr.label_list(
- doc = """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.""",
- allow_files = [".js"],
- ),
- "data": attr.label_list(
- doc = "Runtime dependencies",
- ),
- "karma": attr.label(
- default = Label(_DEFAULT_KARMA_BIN),
- executable = True,
- cfg = "target",
- allow_files = True,
- ),
- "static_files": attr.label_list(
- doc = """Arbitrary files which are available to be served on request.
- Files are served at:
- `/base/<WORKSPACE_NAME>/<path-to-file>`, e.g.
- `/base/build_bazel_rules_typescript/examples/testing/static_script.js`""",
- allow_files = True,
- ),
- "runtime_deps": attr.label_list(
- doc = """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.""",
- allow_files = True,
- aspects = [sources_aspect],
- ),
- "deps": attr.label_list(
- doc = "Other targets which produce JavaScript such as `ts_library`",
- allow_files = True,
- aspects = [sources_aspect],
- ),
- "_conf_tmpl": attr.label(
- default = Label(_CONF_TMPL),
- allow_single_file = True,
- ),
- },
+ attrs = TS_WEB_TEST_ATTRS,
)
-"""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.
-
-Currently this rule uses Karma as the test runner, but this is an implementation
-detail. We might switch to another runner like Jest in the future.
-"""
-
-# This macro exists only to modify the users rule definition a bit.
-# DO NOT add composition of additional rules here.
-def ts_web_test_macro(
- karma = Label(_DEFAULT_KARMA_BIN),
- tags = [],
+def ts_web_test(
+ srcs = [],
+ deps = [],
data = [],
+ configuration_env_vars = [],
+ bootstrap = [],
+ runtime_deps = [],
+ static_files = [],
+ tags = [],
**kwargs):
- """ibazel wrapper for `ts_web_test`
+ """Runs unit tests in a browser.
- This macro re-exposes the `ts_web_test` rule with some extra tags so that
- it behaves correctly under ibazel.
+ 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.
- This is re-exported in `//:defs.bzl` as `ts_web_test` so if you load the rule
- from there, you actually get this macro.
+ 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:
- karma: karma binary label
- tags: standard Bazel tags, this macro adds a couple for ibazel
- data: runtime dependencies
- **kwargs: passed through to `ts_web_test`
+ 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/build_bazel_rules_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(
- karma = karma,
+ _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",
],
- # Our binary dependency must be in data[] for collect_data to pick it up
- # FIXME: maybe we can just ask the attr.karma for its runfiles attr
- data = data + [karma],
**kwargs
)
def ts_web_test_suite(
name,
browsers = ["@io_bazel_rules_webtesting//browsers:chromium-local"],
- karma = Label(_DEFAULT_KARMA_BIN),
args = None,
browser_overrides = None,
config = None,
@@ -300,10 +129,12 @@
**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.
- karma: karma binary label
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
@@ -316,12 +147,12 @@
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 target.
+ 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.
+ 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.
"""
@@ -334,16 +165,8 @@
wrapped_test_name = name + "_wrapped_test"
- # Users don't need to know that this tag is required to run under ibazel
- tags = tags + ["ibazel_notify_changes"]
-
- # Our binary dependency must be in data[] for collect_data to pick it up
- # FIXME: maybe we can just ask the attr.karma for its runfiles attr
- web_test_data = web_test_data + [karma]
-
- ts_web_test(
+ _ts_web_test(
name = wrapped_test_name,
- karma = karma,
args = args,
flaky = flaky,
local = local,
@@ -367,7 +190,10 @@
local = local,
shard_count = shard_count,
size = size,
- tags = tags,
+ 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,
diff --git a/internal/karma/web_test.bzl b/internal/karma/web_test.bzl
new file mode 100644
index 0000000..b40d4e0
--- /dev/null
+++ b/internal/karma/web_test.bzl
@@ -0,0 +1,40 @@
+# 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.
+"Common web_test attributes"
+
+load("@build_bazel_rules_nodejs//internal:node.bzl", "sources_aspect")
+
+# Attributes shared by any web_test rule (ts_web_test, karma_web_test, protractor_web_test)
+COMMON_WEB_TEST_ATTRS = {
+ "srcs": attr.label_list(
+ doc = "A list of JavaScript test files",
+ allow_files = [".js"],
+ ),
+ "configuration_env_vars": attr.string_list(
+ doc = """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.""",
+ default = [],
+ ),
+ "data": attr.label_list(
+ doc = "Runtime dependencies",
+ allow_files = True,
+ ),
+ "deps": attr.label_list(
+ doc = "Other targets which produce JavaScript such as `ts_library`",
+ allow_files = True,
+ aspects = [sources_aspect],
+ ),
+}
diff --git a/package.json b/package.json
index 4140a45..724a1f2 100644
--- a/package.json
+++ b/package.json
@@ -8,8 +8,9 @@
"karma-chrome-launcher": "2.2.0",
"karma-firefox-launcher": "1.1.0",
"karma-jasmine": "1.1.1",
+ "karma-json-result-reporter": "1.0.0",
"karma-requirejs": "1.1.0",
- "karma-sauce-launcher": "1.2.0",
+ "karma-sauce-launcher": "2.0.2",
"karma-sourcemap-loader": "0.3.7",
"protobufjs": "5.0.3",
"requirejs": "2.3.5",
diff --git a/yarn.lock b/yarn.lock
index 20b3f83..c6df00c 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -197,32 +197,6 @@
resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==
-archiver-utils@^1.3.0:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/archiver-utils/-/archiver-utils-1.3.0.tgz#e50b4c09c70bf3d680e32ff1b7994e9f9d895174"
- integrity sha1-5QtMCccL89aA4y/xt5lOn52JUXQ=
- dependencies:
- glob "^7.0.0"
- graceful-fs "^4.1.0"
- lazystream "^1.0.0"
- lodash "^4.8.0"
- normalize-path "^2.0.0"
- readable-stream "^2.0.0"
-
-archiver@2.1.1:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/archiver/-/archiver-2.1.1.tgz#ff662b4a78201494a3ee544d3a33fe7496509ebc"
- integrity sha1-/2YrSnggFJSj7lRNOjP+dJZQnrw=
- dependencies:
- archiver-utils "^1.3.0"
- async "^2.0.0"
- buffer-crc32 "^0.2.1"
- glob "^7.0.0"
- lodash "^4.8.0"
- readable-stream "^2.0.0"
- tar-stream "^1.5.0"
- zip-stream "^1.2.0"
-
are-we-there-yet@~1.1.2:
version "1.1.5"
resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21"
@@ -333,19 +307,12 @@
resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8"
integrity sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==
-async@2.0.1:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/async/-/async-2.0.1.tgz#b709cc0280a9c36f09f4536be823c838a9049e25"
- integrity sha1-twnMAoCpw28J9FNr6CPIOKkEniU=
- dependencies:
- lodash "^4.8.0"
-
async@^1.5.2:
version "1.5.2"
resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a"
integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=
-async@^2.0.0, async@^2.1.2, async@~2.6.0:
+async@^2.1.2, async@~2.6.0:
version "2.6.1"
resolved "https://registry.yarnpkg.com/async/-/async-2.6.1.tgz#b245a23ca71930044ec53fa46aa00a3e87c6a610"
integrity sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==
@@ -404,11 +371,6 @@
resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz#73926771923b5a19747ad666aa5cd4bf9c6e9ce8"
integrity sha1-c5JncZI7Whl0etZmqlzUv5xunOg=
-base64-js@^1.0.2:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.0.tgz#cab1e6118f051095e58b5281aea8c1cd22bfc0e3"
- integrity sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==
-
base64id@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/base64id/-/base64id-1.0.0.tgz#47688cb99bb6804f0e06d3e763b1c32e57d8e6b6"
@@ -453,14 +415,6 @@
dependencies:
buffer-more-ints "0.0.2"
-bl@^1.0.0:
- version "1.2.2"
- resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.2.tgz#a160911717103c07410cef63ef51b397c025af9c"
- integrity sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==
- dependencies:
- readable-stream "^2.3.5"
- safe-buffer "^5.1.1"
-
bl@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/bl/-/bl-1.1.2.tgz#fdca871a99713aa00d19e3bbba41c44787a65398"
@@ -567,7 +521,7 @@
resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0"
integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==
-buffer-alloc@^1.1.0, buffer-alloc@^1.2.0:
+buffer-alloc@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec"
integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==
@@ -575,11 +529,6 @@
buffer-alloc-unsafe "^1.1.0"
buffer-fill "^1.0.0"
-buffer-crc32@^0.2.1:
- version "0.2.13"
- resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242"
- integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=
-
buffer-fill@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c"
@@ -595,14 +544,6 @@
resolved "https://registry.yarnpkg.com/buffer-more-ints/-/buffer-more-ints-0.0.2.tgz#26b3885d10fa13db7fc01aae3aab870199e0124c"
integrity sha1-JrOIXRD6E9t/wBquOquHAZngEkw=
-buffer@^5.1.0:
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.2.1.tgz#dd57fa0f109ac59c602479044dca7b8b3d0b71d6"
- integrity sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==
- dependencies:
- base64-js "^1.0.2"
- ieee754 "^1.1.4"
-
buildmail@4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/buildmail/-/buildmail-4.0.1.tgz#877f7738b78729871c9a105e3b837d2be11a7a72"
@@ -825,16 +766,6 @@
resolved "https://registry.yarnpkg.com/component-inherit/-/component-inherit-0.0.3.tgz#645fc4adf58b72b649d5cae65135619db26ff143"
integrity sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=
-compress-commons@^1.2.0:
- version "1.2.2"
- resolved "https://registry.yarnpkg.com/compress-commons/-/compress-commons-1.2.2.tgz#524a9f10903f3a813389b0225d27c48bb751890f"
- integrity sha1-UkqfEJA/OoEzibAiXSfEi7dRiQ8=
- dependencies:
- buffer-crc32 "^0.2.1"
- crc32-stream "^2.0.0"
- normalize-path "^2.0.0"
- readable-stream "^2.0.0"
-
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
@@ -904,21 +835,6 @@
resolved "https://registry.yarnpkg.com/corser/-/corser-2.0.1.tgz#8eda252ecaab5840dcd975ceb90d9370c819ff87"
integrity sha1-jtolLsqrWEDc2XXOuQ2TcMgZ/4c=
-crc32-stream@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/crc32-stream/-/crc32-stream-2.0.0.tgz#e3cdd3b4df3168dd74e3de3fbbcb7b297fe908f4"
- integrity sha1-483TtN8xaN10494/u8t7KX/pCPQ=
- dependencies:
- crc "^3.4.4"
- readable-stream "^2.0.0"
-
-crc@^3.4.4:
- version "3.8.0"
- resolved "https://registry.yarnpkg.com/crc/-/crc-3.8.0.tgz#ad60269c2c856f8c299e2c4cc0de4556914056c6"
- integrity sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==
- dependencies:
- buffer "^5.1.0"
-
cryptiles@2.x.x:
version "2.0.5"
resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8"
@@ -1105,13 +1021,6 @@
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=
-end-of-stream@^1.0.0:
- version "1.4.1"
- resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43"
- integrity sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==
- dependencies:
- once "^1.4.0"
-
engine.io-client@~3.1.0:
version "3.1.6"
resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-3.1.6.tgz#5bdeb130f8b94a50ac5cbeb72583e7a4a063ddfd"
@@ -1449,11 +1358,6 @@
dependencies:
null-check "^1.0.0"
-fs-constants@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad"
- integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==
-
fs-minipass@^1.2.5:
version "1.2.5"
resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d"
@@ -1482,6 +1386,11 @@
readable-stream "1.1.x"
xregexp "2.0.0"
+fun-map@^3.3.1:
+ version "3.3.1"
+ resolved "https://registry.yarnpkg.com/fun-map/-/fun-map-3.3.1.tgz#6415fde3b93ad58f9ee9566236cff3e3c64b94cb"
+ integrity sha1-ZBX947k61Y+e6VZiNs/z48ZLlMs=
+
gauge@~2.7.3:
version "2.7.4"
resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7"
@@ -1596,7 +1505,7 @@
pify "^2.0.0"
pinkie-promise "^2.0.0"
-graceful-fs@^4.1.0, graceful-fs@^4.1.11, graceful-fs@^4.1.2:
+graceful-fs@^4.1.11, graceful-fs@^4.1.2:
version "4.1.11"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
integrity sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=
@@ -1850,11 +1759,6 @@
dependencies:
safer-buffer ">= 2.1.2 < 3"
-ieee754@^1.1.4:
- version "1.1.12"
- resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.12.tgz#50bf24e5b9c8bb98af4964c941cdb0918da7b60b"
- integrity sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==
-
ignore-walk@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8"
@@ -2244,20 +2148,26 @@
resolved "https://registry.yarnpkg.com/karma-jasmine/-/karma-jasmine-1.1.1.tgz#6fe840e75a11600c9d91e84b33c458e1c46a3529"
integrity sha1-b+hA51oRYAydkehLM8RY4cRqNSk=
+karma-json-result-reporter@1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/karma-json-result-reporter/-/karma-json-result-reporter-1.0.0.tgz#9bfaa17d610470d08556e48ccbaf64d7950c7255"
+ integrity sha1-m/qhfWEEcNCFVuSMy69k15UMclU=
+ dependencies:
+ fun-map "^3.3.1"
+
karma-requirejs@1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/karma-requirejs/-/karma-requirejs-1.1.0.tgz#fddae2cb87d7ebc16fb0222893564d7fee578798"
integrity sha1-/driy4fX68FvsCIok1ZNf+5Xh5g=
-karma-sauce-launcher@1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/karma-sauce-launcher/-/karma-sauce-launcher-1.2.0.tgz#6f2558ddef3cf56879fa27540c8ae9f8bfd16bca"
- integrity sha512-lEhtGRGS+3Yw6JSx/vJY9iQyHNtTjcojrSwNzqNUOaDceKDu9dPZqA/kr69bUO9G2T6GKbu8AZgXqy94qo31Jg==
+karma-sauce-launcher@2.0.2:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/karma-sauce-launcher/-/karma-sauce-launcher-2.0.2.tgz#dbf98e70d86bf287b03a537cf637eb7aefa975c3"
+ integrity sha512-jLUFaJhHMcKpxFWUesyWYihzM5FvQiJsDwGcCtKeOy2lsWhkVw0V0Byqb1d+wU6myU1mribBtsIcub23HS4kWA==
dependencies:
- q "^1.5.0"
- sauce-connect-launcher "^1.2.2"
- saucelabs "^1.4.0"
- wd "^1.4.0"
+ sauce-connect-launcher "^1.2.4"
+ saucelabs "^1.5.0"
+ selenium-webdriver "^4.0.0-alpha.1"
karma-sourcemap-loader@0.3.7:
version "0.3.7"
@@ -2322,13 +2232,6 @@
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051"
integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==
-lazystream@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/lazystream/-/lazystream-1.0.0.tgz#f6995fe0f820392f61396be89462407bb77168e4"
- integrity sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=
- dependencies:
- readable-stream "^2.0.5"
-
lcid@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835"
@@ -2370,12 +2273,7 @@
dependencies:
immediate "~3.0.5"
-lodash@4.17.10:
- version "4.17.10"
- resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7"
- integrity sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==
-
-lodash@^4.0.0, lodash@^4.15.0, lodash@^4.16.6, lodash@^4.17.10, lodash@^4.17.4, lodash@^4.5.0, lodash@^4.8.0:
+lodash@^4.0.0, lodash@^4.15.0, lodash@^4.16.6, lodash@^4.17.10, lodash@^4.17.4, lodash@^4.5.0:
version "4.17.11"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d"
integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==
@@ -2815,7 +2713,7 @@
dependencies:
ee-first "1.1.1"
-once@^1.3.0, once@^1.4.0:
+once@^1.3.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
@@ -3111,11 +3009,6 @@
resolved "https://registry.yarnpkg.com/q/-/q-1.4.1.tgz#55705bcd93c5f3673530c2c2cbc0c2b3addc286e"
integrity sha1-VXBbzZPF82c1MMLCy8DCs63cKG4=
-q@^1.5.0:
- version "1.5.1"
- resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"
- integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=
-
qjobs@^1.1.4:
version "1.2.0"
resolved "https://registry.yarnpkg.com/qjobs/-/qjobs-1.2.0.tgz#c45e9c61800bd087ef88d7e256423bdd49e5d071"
@@ -3185,7 +3078,7 @@
isarray "0.0.1"
string_decoder "~0.10.x"
-readable-stream@2, readable-stream@^2.0.0, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.3.0, readable-stream@^2.3.5:
+readable-stream@2, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.3.0:
version "2.3.6"
resolved "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf"
integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==
@@ -3307,34 +3200,6 @@
tough-cookie "~2.3.0"
tunnel-agent "~0.4.1"
-request@2.85.0:
- version "2.85.0"
- resolved "http://registry.npmjs.org/request/-/request-2.85.0.tgz#5a03615a47c61420b3eb99b7dba204f83603e1fa"
- integrity sha512-8H7Ehijd4js+s6wuVPLjwORxD4zeuyjYugprdOXlPSqaApmL/QOy+EB/beICHVCHkGMKNh5rvihb5ov+IDw4mg==
- dependencies:
- aws-sign2 "~0.7.0"
- aws4 "^1.6.0"
- caseless "~0.12.0"
- combined-stream "~1.0.5"
- extend "~3.0.1"
- forever-agent "~0.6.1"
- form-data "~2.3.1"
- har-validator "~5.0.3"
- hawk "~6.0.2"
- http-signature "~1.2.0"
- is-typedarray "~1.0.0"
- isstream "~0.1.2"
- json-stringify-safe "~5.0.1"
- mime-types "~2.1.17"
- oauth-sign "~0.8.2"
- performance-now "^2.1.0"
- qs "~6.5.1"
- safe-buffer "^5.1.1"
- stringstream "~0.0.5"
- tough-cookie "~2.3.3"
- tunnel-agent "^0.6.0"
- uuid "^3.1.0"
-
request@^2.0.0, request@^2.74.0:
version "2.88.0"
resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef"
@@ -3460,7 +3325,7 @@
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
-sauce-connect-launcher@^1.2.2:
+sauce-connect-launcher@^1.2.4:
version "1.2.4"
resolved "https://registry.yarnpkg.com/sauce-connect-launcher/-/sauce-connect-launcher-1.2.4.tgz#8d38f85242a9fbede1b2303b559f7e20c5609a1c"
integrity sha512-X2vfwulR6brUGiicXKxPm1GJ7dBEeP1II450Uv4bHGrcGOapZNgzJvn9aioea5IC5BPp/7qjKdE3xbbTBIVXMA==
@@ -3471,7 +3336,7 @@
lodash "^4.16.6"
rimraf "^2.5.4"
-saucelabs@^1.4.0:
+saucelabs@^1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/saucelabs/-/saucelabs-1.5.0.tgz#9405a73c360d449b232839919a86c396d379fd9d"
integrity sha512-jlX3FGdWvYf4Q3LFfFWS1QvPg3IGCGWxIc8QBFdPTbpTJnt/v17FHXYVAn7C8sHf1yUXo2c7yIM0isDryfYtHQ==
@@ -3516,6 +3381,16 @@
ws "^1.0.1"
xml2js "0.4.4"
+selenium-webdriver@^4.0.0-alpha.1:
+ version "4.0.0-alpha.1"
+ resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-4.0.0-alpha.1.tgz#cc93415e21d2dc1dfd85dfc5f6b55f3ac53933b1"
+ integrity sha512-z88rdjHAv3jmTZ7KSGUkTvo4rGzcDGMq0oXWHNIDK96Gs31JKVdu9+FMtT4KBrVoibg8dUicJDok6GnqqttO5Q==
+ dependencies:
+ jszip "^3.1.3"
+ rimraf "^2.5.4"
+ tmp "0.0.30"
+ xml2js "^0.4.17"
+
semver@^5.3.0:
version "5.4.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e"
@@ -3904,19 +3779,6 @@
dependencies:
has-flag "^1.0.0"
-tar-stream@^1.5.0:
- version "1.6.1"
- resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.6.1.tgz#f84ef1696269d6223ca48f6e1eeede3f7e81f395"
- integrity sha512-IFLM5wp3QrJODQFPm6/to3LJZrONdBY/otxcvDIQzu217zKye6yVR3hhi9lAjrC2Z+m/j5oDxMPb1qcd8cIvpA==
- dependencies:
- bl "^1.0.0"
- buffer-alloc "^1.1.0"
- end-of-stream "^1.0.0"
- fs-constants "^1.0.0"
- readable-stream "^2.3.0"
- to-buffer "^1.1.0"
- xtend "^4.0.0"
-
tar@^4:
version "4.4.6"
resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.6.tgz#63110f09c00b4e60ac8bcfe1bf3c8660235fbc9b"
@@ -3964,11 +3826,6 @@
resolved "https://registry.yarnpkg.com/to-array/-/to-array-0.1.4.tgz#17e6c11f73dd4f3d74cda7a4ff3238e9ad9bf890"
integrity sha1-F+bBH3PdTz10zaek/zI46a2b+JA=
-to-buffer@^1.1.0:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.1.1.tgz#493bd48f62d7c43fcded313a03dcadb2e1213a80"
- integrity sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==
-
to-object-path@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af"
@@ -4187,11 +4044,6 @@
resolved "https://registry.yarnpkg.com/uws/-/uws-9.14.0.tgz#fac8386befc33a7a3705cbd58dc47b430ca4dd95"
integrity sha512-HNMztPP5A1sKuVFmdZ6BPVpBQd5bUjNC8EFMFiICK+oho/OQsAJy5hnIx4btMHiOk8j04f/DbIlqnEZ9d72dqg==
-vargs@0.1.0:
- version "0.1.0"
- resolved "https://registry.yarnpkg.com/vargs/-/vargs-0.1.0.tgz#6b6184da6520cc3204ce1b407cac26d92609ebff"
- integrity sha1-a2GE2mUgzDIEzhtAfKwm2SYJ6/8=
-
verror@1.10.0:
version "1.10.0"
resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400"
@@ -4206,19 +4058,6 @@
resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec"
integrity sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=
-wd@^1.4.0:
- version "1.10.3"
- resolved "https://registry.yarnpkg.com/wd/-/wd-1.10.3.tgz#395ac7eb58a98e556369f8f8e5f845d91fb152a3"
- integrity sha512-ffqqZDtFFLeg5u/4pw2vYKECW+z+vW6vc+7rcqF15uu1/rmw3BydV84BONNc9DIcQ5Z7gQFS/hAuMvj53eVtSg==
- dependencies:
- archiver "2.1.1"
- async "2.0.1"
- lodash "4.17.10"
- mkdirp "^0.5.1"
- q "1.4.1"
- request "2.85.0"
- vargs "0.1.0"
-
webdriver-js-extender@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/webdriver-js-extender/-/webdriver-js-extender-1.0.0.tgz#81c533a9e33d5bfb597b4e63e2cdb25b54777515"
@@ -4386,13 +4225,3 @@
version "0.1.2"
resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419"
integrity sha1-AI4G2AlDIMNy28L47XagymyKxBk=
-
-zip-stream@^1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/zip-stream/-/zip-stream-1.2.0.tgz#a8bc45f4c1b49699c6b90198baacaacdbcd4ba04"
- integrity sha1-qLxF9MG0lpnGuQGYuqyqzbzUugQ=
- dependencies:
- archiver-utils "^1.3.0"
- compress-commons "^1.2.0"
- lodash "^4.8.0"
- readable-stream "^2.0.0"