Skip to content

Commit 71e0df0

Browse files
mrmekumatsko
authored andcommittedJul 12, 2018
feat(bazel): Initial commit of protractor_web_test_suite (#24787)
Co-authored-by: Andrew Z Allen <me@andrewzallen.com> PR Close #24787
1 parent 0399c69 commit 71e0df0

File tree

10 files changed

+224
-0
lines changed

10 files changed

+224
-0
lines changed
 

‎BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ node_modules_filegroup(
2222
"jasmine",
2323
"minimist",
2424
"protobufjs",
25+
"protractor",
2526
"reflect-metadata",
2627
"source-map-support",
2728
"tsickle",

‎WORKSPACE

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ http_archive(
1111
sha256 = "634206524d90dc03c52392fa3f19a16637d2bcf154910436fe1d669a0d9d7b9c",
1212
)
1313

14+
http_archive(
15+
name = "bazel_gazelle",
16+
sha256 = "d03625db67e9fb0905bbd206fa97e32ae9da894fe234a493e7517fd25faec914",
17+
url = "https://github.com/bazelbuild/bazel-gazelle/releases/download/0.10.1/bazel-gazelle-0.10.1.tar.gz",
18+
)
19+
1420
http_archive(
1521
name = "io_bazel_rules_webtesting",
1622
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
8591
go_rules_dependencies()
8692
go_register_toolchains()
8793

94+
load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies")
95+
96+
gazelle_dependencies()
97+
8898
load("@io_bazel_rules_webtesting//web:repositories.bzl", "browser_repositories", "web_test_repositories")
8999

90100
web_test_repositories()

‎packages/bazel/index.bzl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ Users should not load files under "/src"
99

1010
load("//packages/bazel/src:ng_module.bzl", _ng_module = "ng_module")
1111
load("//packages/bazel/src/ng_package:ng_package.bzl", _ng_package = "ng_package")
12+
load("//packages/bazel/src/protractor:protractor_web_test_suite.bzl", _protractor_web_test_suite = "protractor_web_test_suite")
1213

1314
ng_module = _ng_module
1415
ng_package = _ng_package
16+
protractor_web_test_suite = _protractor_web_test_suite
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
exports_files([
2+
"conf.js.tmpl",
3+
"protractor_runner.js",
4+
])
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
const baseConf = require("BASE_CONF_IMPORT_PATH");
2+
3+
exports.config = {
4+
...baseConf.config,
5+
framework: "jasmine2",
6+
seleniumAddress: process.env.WEB_TEST_HTTP_SERVER.trim() + "/wd/hub",
7+
specs: [
8+
SPEC_FILE_IMPORT_PATHS
9+
].map(specPath => require.resolve(specPath)),
10+
// TODO: Allow users to specifify other browsers.
11+
capabilities: {
12+
browserName: "chrome"
13+
},
14+
};
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*
8+
* @fileoverview A wrapper around the protractor cli for bazel compatibility.
9+
*/
10+
11+
const launcher = require('protractor/built/launcher');
12+
13+
function main(args) {
14+
if (!args.length) {
15+
throw new Error('Config file argument missing');
16+
}
17+
const config = require.resolve(args[0]);
18+
launcher.init(config);
19+
}
20+
21+
if (require.main === module) {
22+
process.exitCode = main(process.argv.slice(2));
23+
}
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# Copyright Google Inc. All Rights Reserved.
2+
#
3+
# Use of this source code is governed by an MIT-style license that can be
4+
# found in the LICENSE file at https://angular.io/license
5+
"""Implementation of the protractor_web_test_suite rule.
6+
"""
7+
8+
load("@io_bazel_rules_webtesting//web:web.bzl", "web_test_suite")
9+
load("@build_bazel_rules_nodejs//:defs.bzl", "nodejs_binary")
10+
load("@build_bazel_rules_nodejs//internal/common:sources_aspect.bzl", "sources_aspect")
11+
load("@build_bazel_rules_nodejs//internal/common:module_mappings.bzl", "module_mappings_runtime_aspect")
12+
13+
def _modify_tsconfig_impl(ctx):
14+
spec_file_import_paths = []
15+
for dep in ctx.attr.deps:
16+
# For each transitive ES5 dependency, grab the short path
17+
for f in dep.node_sources.to_list():
18+
spec_file_import_paths.append("\"{workspace}/{path}\"".format(workspace=ctx.workspace_name, path=f.short_path))
19+
20+
ctx.actions.expand_template(
21+
template = ctx.file._conf_templ,
22+
output = ctx.outputs._modified_conf,
23+
substitutions = {
24+
"BASE_CONF_IMPORT_PATH": "{workspace}/{path}".format(workspace=ctx.workspace_name, path=ctx.file.base_conf.short_path),
25+
"SPEC_FILE_IMPORT_PATHS": ',\n '.join(spec_file_import_paths),
26+
})
27+
28+
_modify_conf = rule(
29+
attrs = {
30+
"base_conf": attr.label(
31+
doc = """conf.js file used to configure protractor.""",
32+
allow_single_file = True,
33+
cfg = "data",
34+
aspects = [
35+
sources_aspect,
36+
module_mappings_runtime_aspect,
37+
],
38+
),
39+
"deps": attr.label_list(
40+
doc = """Spec and page files used for testing.""",
41+
allow_files = True,
42+
cfg = "data",
43+
aspects = [
44+
sources_aspect,
45+
module_mappings_runtime_aspect,
46+
],
47+
),
48+
"_conf_templ": attr.label(
49+
allow_files = True,
50+
single_file = True,
51+
default = Label("@angular//packages/bazel/src/protractor:conf.js.tmpl"),
52+
),
53+
},
54+
outputs = {
55+
"_modified_conf": "%{name}.conf.js",
56+
},
57+
implementation = _modify_tsconfig_impl,
58+
)
59+
60+
def protractor_web_test_suite(name, conf, deps, data = [], **kwargs):
61+
"""Runs protractor using the passed conf.js file and tests listed within deps.
62+
63+
Args:
64+
name: The name of the web_test_suite rule the macro expands into.
65+
conf: A conf.js file to be used as a base template. The following fields of the base
66+
config are overridden:
67+
framework
68+
seleniumAddress
69+
specs
70+
capabilities
71+
deps: A list of dependencies containing the test files to run within protractor.
72+
data: Any runtime files which are needed to run the test suite.
73+
**kwargs: Any other arguements are passed directory to the expanded web_test_suite rule.
74+
75+
Returns:
76+
This macro expands into a web_test_suite rule which runs the protractor tests.
77+
"""
78+
79+
_modify_conf_name = "%s_modify_conf" % name
80+
_modify_conf(
81+
name = _modify_conf_name,
82+
base_conf = conf,
83+
deps = deps,
84+
testonly = True,
85+
)
86+
87+
_modified_conf = "%s.conf.js" % _modify_conf_name
88+
89+
_protractor_runner_name = name + "_protractor_runner"
90+
nodejs_binary(
91+
name = _protractor_runner_name,
92+
entry_point = "angular/packages/bazel/src/protractor/protractor_runner.js",
93+
data = data + deps + [_modified_conf, "@angular//packages/bazel/src/protractor:protractor_runner.js"],
94+
templated_args = ["$(location :%s)" % _modified_conf],
95+
tags = ["manual"],
96+
testonly = True,
97+
)
98+
99+
web_test_suite(
100+
name = name,
101+
# TODO: Allow users to specify more browsers. Currently conf.js is hardcoded for chrome.
102+
browsers = ["@io_bazel_rules_webtesting//browsers:chromium-local"],
103+
data = data + deps + [conf, _modified_conf],
104+
test = ":%s_bin" % _protractor_runner_name,
105+
testonly = True,
106+
**kwargs
107+
)
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
load("//packages/bazel:index.bzl", "protractor_web_test_suite")
2+
load("@build_bazel_rules_typescript//:defs.bzl", "ts_library")
3+
4+
ts_library(
5+
name = "ts_spec",
6+
testonly = True,
7+
srcs = ["test.spec.ts"],
8+
)
9+
10+
protractor_web_test_suite(
11+
name = "demo",
12+
conf = "conf.js",
13+
deps = [":ts_spec"],
14+
)
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
/**
10+
* @fileoverview A demo of what a user's conf.js file might look like.
11+
*/
12+
const http = require('http');
13+
14+
const PORT = 3000;
15+
16+
exports.config = {
17+
baseUrl: `http://localhost:${PORT}`,
18+
onPrepare() {
19+
const app = new http.Server();
20+
21+
app.on('request', (req, res) => {
22+
res.writeHead(200, {'Content-Type': 'text/plain'});
23+
res.write('Hello World');
24+
res.end('\n');
25+
});
26+
27+
return new Promise(resolve => { app.listen(PORT, () => { resolve(); }); });
28+
}
29+
};
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*
8+
* @fileoverview A small demo of how to run a protractor test.
9+
*/
10+
11+
import {$, browser} from 'protractor';
12+
13+
describe('Basic test', () => {
14+
it('should say hello world', () => {
15+
browser.waitForAngularEnabled(false);
16+
browser.get('/');
17+
18+
expect($('body').getText()).toContain('Hello World');
19+
});
20+
});

0 commit comments

Comments
 (0)
Please sign in to comment.