feat(bazel): Initial commit of protractor_web_test_suite (#24787)
Co-authored-by: Andrew Z Allen <me@andrewzallen.com> PR Close #24787
This commit is contained in:
parent
0399c6972a
commit
71e0df039c
|
@ -22,6 +22,7 @@ node_modules_filegroup(
|
|||
"jasmine",
|
||||
"minimist",
|
||||
"protobufjs",
|
||||
"protractor",
|
||||
"reflect-metadata",
|
||||
"source-map-support",
|
||||
"tsickle",
|
||||
|
|
10
WORKSPACE
10
WORKSPACE
|
@ -11,6 +11,12 @@ http_archive(
|
|||
sha256 = "634206524d90dc03c52392fa3f19a16637d2bcf154910436fe1d669a0d9d7b9c",
|
||||
)
|
||||
|
||||
http_archive(
|
||||
name = "bazel_gazelle",
|
||||
sha256 = "d03625db67e9fb0905bbd206fa97e32ae9da894fe234a493e7517fd25faec914",
|
||||
url = "https://github.com/bazelbuild/bazel-gazelle/releases/download/0.10.1/bazel-gazelle-0.10.1.tar.gz",
|
||||
)
|
||||
|
||||
http_archive(
|
||||
name = "io_bazel_rules_webtesting",
|
||||
url = "https://github.com/bazelbuild/rules_webtesting/archive/v0.2.0.zip",
|
||||
|
@ -85,6 +91,10 @@ load("@io_bazel_rules_go//go:def.bzl", "go_rules_dependencies", "go_register_too
|
|||
go_rules_dependencies()
|
||||
go_register_toolchains()
|
||||
|
||||
load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies")
|
||||
|
||||
gazelle_dependencies()
|
||||
|
||||
load("@io_bazel_rules_webtesting//web:repositories.bzl", "browser_repositories", "web_test_repositories")
|
||||
|
||||
web_test_repositories()
|
||||
|
|
|
@ -9,6 +9,8 @@ Users should not load files under "/src"
|
|||
|
||||
load("//packages/bazel/src:ng_module.bzl", _ng_module = "ng_module")
|
||||
load("//packages/bazel/src/ng_package:ng_package.bzl", _ng_package = "ng_package")
|
||||
load("//packages/bazel/src/protractor:protractor_web_test_suite.bzl", _protractor_web_test_suite = "protractor_web_test_suite")
|
||||
|
||||
ng_module = _ng_module
|
||||
ng_package = _ng_package
|
||||
protractor_web_test_suite = _protractor_web_test_suite
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
exports_files([
|
||||
"conf.js.tmpl",
|
||||
"protractor_runner.js",
|
||||
])
|
|
@ -0,0 +1,14 @@
|
|||
const baseConf = require("BASE_CONF_IMPORT_PATH");
|
||||
|
||||
exports.config = {
|
||||
...baseConf.config,
|
||||
framework: "jasmine2",
|
||||
seleniumAddress: process.env.WEB_TEST_HTTP_SERVER.trim() + "/wd/hub",
|
||||
specs: [
|
||||
SPEC_FILE_IMPORT_PATHS
|
||||
].map(specPath => require.resolve(specPath)),
|
||||
// TODO: Allow users to specifify other browsers.
|
||||
capabilities: {
|
||||
browserName: "chrome"
|
||||
},
|
||||
};
|
|
@ -0,0 +1,23 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*
|
||||
* @fileoverview A wrapper around the protractor cli for bazel compatibility.
|
||||
*/
|
||||
|
||||
const launcher = require('protractor/built/launcher');
|
||||
|
||||
function main(args) {
|
||||
if (!args.length) {
|
||||
throw new Error('Config file argument missing');
|
||||
}
|
||||
const config = require.resolve(args[0]);
|
||||
launcher.init(config);
|
||||
}
|
||||
|
||||
if (require.main === module) {
|
||||
process.exitCode = main(process.argv.slice(2));
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
# Copyright Google Inc. All Rights Reserved.
|
||||
#
|
||||
# Use of this source code is governed by an MIT-style license that can be
|
||||
# found in the LICENSE file at https://angular.io/license
|
||||
"""Implementation of the protractor_web_test_suite rule.
|
||||
"""
|
||||
|
||||
load("@io_bazel_rules_webtesting//web:web.bzl", "web_test_suite")
|
||||
load("@build_bazel_rules_nodejs//:defs.bzl", "nodejs_binary")
|
||||
load("@build_bazel_rules_nodejs//internal/common:sources_aspect.bzl", "sources_aspect")
|
||||
load("@build_bazel_rules_nodejs//internal/common:module_mappings.bzl", "module_mappings_runtime_aspect")
|
||||
|
||||
def _modify_tsconfig_impl(ctx):
|
||||
spec_file_import_paths = []
|
||||
for dep in ctx.attr.deps:
|
||||
# For each transitive ES5 dependency, grab the short path
|
||||
for f in dep.node_sources.to_list():
|
||||
spec_file_import_paths.append("\"{workspace}/{path}\"".format(workspace=ctx.workspace_name, path=f.short_path))
|
||||
|
||||
ctx.actions.expand_template(
|
||||
template = ctx.file._conf_templ,
|
||||
output = ctx.outputs._modified_conf,
|
||||
substitutions = {
|
||||
"BASE_CONF_IMPORT_PATH": "{workspace}/{path}".format(workspace=ctx.workspace_name, path=ctx.file.base_conf.short_path),
|
||||
"SPEC_FILE_IMPORT_PATHS": ',\n '.join(spec_file_import_paths),
|
||||
})
|
||||
|
||||
_modify_conf = rule(
|
||||
attrs = {
|
||||
"base_conf": attr.label(
|
||||
doc = """conf.js file used to configure protractor.""",
|
||||
allow_single_file = True,
|
||||
cfg = "data",
|
||||
aspects = [
|
||||
sources_aspect,
|
||||
module_mappings_runtime_aspect,
|
||||
],
|
||||
),
|
||||
"deps": attr.label_list(
|
||||
doc = """Spec and page files used for testing.""",
|
||||
allow_files = True,
|
||||
cfg = "data",
|
||||
aspects = [
|
||||
sources_aspect,
|
||||
module_mappings_runtime_aspect,
|
||||
],
|
||||
),
|
||||
"_conf_templ": attr.label(
|
||||
allow_files = True,
|
||||
single_file = True,
|
||||
default = Label("@angular//packages/bazel/src/protractor:conf.js.tmpl"),
|
||||
),
|
||||
},
|
||||
outputs = {
|
||||
"_modified_conf": "%{name}.conf.js",
|
||||
},
|
||||
implementation = _modify_tsconfig_impl,
|
||||
)
|
||||
|
||||
def protractor_web_test_suite(name, conf, deps, data = [], **kwargs):
|
||||
"""Runs protractor using the passed conf.js file and tests listed within deps.
|
||||
|
||||
Args:
|
||||
name: The name of the web_test_suite rule the macro expands into.
|
||||
conf: A conf.js file to be used as a base template. The following fields of the base
|
||||
config are overridden:
|
||||
framework
|
||||
seleniumAddress
|
||||
specs
|
||||
capabilities
|
||||
deps: A list of dependencies containing the test files to run within protractor.
|
||||
data: Any runtime files which are needed to run the test suite.
|
||||
**kwargs: Any other arguements are passed directory to the expanded web_test_suite rule.
|
||||
|
||||
Returns:
|
||||
This macro expands into a web_test_suite rule which runs the protractor tests.
|
||||
"""
|
||||
|
||||
_modify_conf_name = "%s_modify_conf" % name
|
||||
_modify_conf(
|
||||
name = _modify_conf_name,
|
||||
base_conf = conf,
|
||||
deps = deps,
|
||||
testonly = True,
|
||||
)
|
||||
|
||||
_modified_conf = "%s.conf.js" % _modify_conf_name
|
||||
|
||||
_protractor_runner_name = name + "_protractor_runner"
|
||||
nodejs_binary(
|
||||
name = _protractor_runner_name,
|
||||
entry_point = "angular/packages/bazel/src/protractor/protractor_runner.js",
|
||||
data = data + deps + [_modified_conf, "@angular//packages/bazel/src/protractor:protractor_runner.js"],
|
||||
templated_args = ["$(location :%s)" % _modified_conf],
|
||||
tags = ["manual"],
|
||||
testonly = True,
|
||||
)
|
||||
|
||||
web_test_suite(
|
||||
name = name,
|
||||
# TODO: Allow users to specify more browsers. Currently conf.js is hardcoded for chrome.
|
||||
browsers = ["@io_bazel_rules_webtesting//browsers:chromium-local"],
|
||||
data = data + deps + [conf, _modified_conf],
|
||||
test = ":%s_bin" % _protractor_runner_name,
|
||||
testonly = True,
|
||||
**kwargs
|
||||
)
|
|
@ -0,0 +1,14 @@
|
|||
load("//packages/bazel:index.bzl", "protractor_web_test_suite")
|
||||
load("@build_bazel_rules_typescript//:defs.bzl", "ts_library")
|
||||
|
||||
ts_library(
|
||||
name = "ts_spec",
|
||||
testonly = True,
|
||||
srcs = ["test.spec.ts"],
|
||||
)
|
||||
|
||||
protractor_web_test_suite(
|
||||
name = "demo",
|
||||
conf = "conf.js",
|
||||
deps = [":ts_spec"],
|
||||
)
|
|
@ -0,0 +1,29 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview A demo of what a user's conf.js file might look like.
|
||||
*/
|
||||
const http = require('http');
|
||||
|
||||
const PORT = 3000;
|
||||
|
||||
exports.config = {
|
||||
baseUrl: `http://localhost:${PORT}`,
|
||||
onPrepare() {
|
||||
const app = new http.Server();
|
||||
|
||||
app.on('request', (req, res) => {
|
||||
res.writeHead(200, {'Content-Type': 'text/plain'});
|
||||
res.write('Hello World');
|
||||
res.end('\n');
|
||||
});
|
||||
|
||||
return new Promise(resolve => { app.listen(PORT, () => { resolve(); }); });
|
||||
}
|
||||
};
|
|
@ -0,0 +1,20 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*
|
||||
* @fileoverview A small demo of how to run a protractor test.
|
||||
*/
|
||||
|
||||
import {$, browser} from 'protractor';
|
||||
|
||||
describe('Basic test', () => {
|
||||
it('should say hello world', () => {
|
||||
browser.waitForAngularEnabled(false);
|
||||
browser.get('/');
|
||||
|
||||
expect($('body').getText()).toContain('Hello World');
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue