Skip to content
This repository was archived by the owner on Feb 22, 2018. It is now read-only.

Commit 6705183

Browse files
committed
test(e2e): add end-to-end tests using ProtractorDart
https://pub.dartlang.org/packages/protractor
1 parent 384039a commit 6705183

13 files changed

+583
-2
lines changed

pubspec.lock

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ packages:
4545
description: intl
4646
source: hosted
4747
version: "0.9.9"
48+
js:
49+
description: js
50+
source: hosted
51+
version: "0.2.2"
4852
logging:
4953
description: logging
5054
source: hosted
@@ -65,6 +69,10 @@ packages:
6569
description: perf_api
6670
source: hosted
6771
version: "0.0.8"
72+
protractor:
73+
description: protractor
74+
source: hosted
75+
version: "0.0.2"
6876
route_hierarchical:
6977
description: route_hierarchical
7078
source: hosted

pubspec.yaml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ dependencies:
2727
web_components: '>=0.3.3 <0.4.0'
2828
dev_dependencies:
2929
benchmark_harness: '>=1.0.0'
30-
unittest: '>=0.10.1 <0.12.0'
31-
mock: '>=0.10.0 <0.12.0'
3230
guinness: '>=0.1.3 <0.2.0'
31+
mock: '>=0.10.0 <0.12.0'
32+
protractor: '0.0.2'
33+
unittest: '>=0.10.1 <0.12.0'

scripts/run-e2e-test.sh

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
#!/bin/bash
2+
3+
# Run E2E / Protractor tests.
4+
5+
set -e
6+
7+
. $(dirname $0)/env.sh
8+
9+
SIGNALS=(ERR HUP INT QUIT PIPE TERM)
10+
11+
_onSignal() {
12+
EXIT_CODE=$?
13+
# Kill all child processes (running servers.)
14+
kill 0
15+
# Need to explicitly kill ourselves to let the caller know we died from a
16+
# signal. Ref: http://www.cons.org/cracauer/sigint.html
17+
sig=$1
18+
trap - "${SIGNALS[@]}" # disable signals so we don't capture them again.
19+
if [[ "$sig" == "ERR" ]]; then
20+
exit $EXIT_CODE
21+
else
22+
kill -$sig $$
23+
fi
24+
}
25+
26+
for s in "${SIGNALS[@]}" ; do
27+
trap "_onSignal $s" $s
28+
done
29+
30+
31+
install_deps() {(
32+
SELENIUM_VER="2.42"
33+
SELENIUM_ZIP="selenium-server-standalone-$SELENIUM_VER.0.jar"
34+
CHROMEDRIVER_VER="2.10"
35+
# chromedriver
36+
case "$(uname -s)" in
37+
(Darwin) CHROMEDRIVER_ZIP="chromedriver_mac32.zip" ;;
38+
(Linux) CHROMEDRIVER_ZIP="chromedriver_linux64.zip" ;;
39+
(*) echo Unsupported OS >&2; exit 2 ;;
40+
esac
41+
mkdir -p e2e_bin && cd e2e_bin
42+
if [[ ! -e "$SELENIUM_ZIP" ]]; then
43+
curl -O "http://selenium-release.storage.googleapis.com/$SELENIUM_VER/$SELENIUM_ZIP"
44+
fi
45+
if [[ ! -e "$CHROMEDRIVER_ZIP" ]]; then
46+
curl -O "http://chromedriver.storage.googleapis.com/$CHROMEDRIVER_VER/$CHROMEDRIVER_ZIP"
47+
unzip "$CHROMEDRIVER_ZIP"
48+
fi
49+
)}
50+
51+
52+
start_servers() {
53+
# Run examples.
54+
(
55+
cd example
56+
pub install
57+
pub build
58+
rsync -rl --exclude packages web/ build/web/
59+
rm -rf build/web/packages
60+
ln -s $PWD/packages build/web/packages
61+
)
62+
PORT=28000
63+
(cd example/build/web && python -m SimpleHTTPServer $PORT) >/dev/null 2>&1 &
64+
export NGDART_EXAMPLE_BASEURL=http://127.0.0.1:$PORT
65+
66+
# Allow chromedriver to be found on the system path.
67+
export PATH=$PATH:$PWD/e2e_bin
68+
69+
# Start selenium. Kill all output - selenium is extremely noisy.
70+
java -jar ./e2e_bin/selenium-server-standalone-2.42.0.jar >/dev/null 2>&1 &
71+
72+
sleep 4 # wait for selenium startup
73+
}
74+
75+
76+
# Main
77+
install_deps
78+
start_servers
79+
(cd test_e2e && pub install)
80+
./node_modules/.bin/protractor_dart test_e2e/examplesConf.js

scripts/run-test.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,5 @@ $NGDART_SCRIPT_DIR/analyze.sh &&
3333
--reporters=junit,dots --port=8765 --runner-port=8766 \
3434
--browsers=Dartium,Chrome,Firefox --single-run --no-colors
3535

36+
# Run E2E tests
37+
$NGDART_BASE_DIR/scripts/run-e2e-test.sh

scripts/travis/build.sh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,13 @@ node "node_modules/karma/bin/karma" start karma.conf \
102102
--reporters=junit,dots --port=8765 --runner-port=8766 \
103103
--browsers=$BROWSERS --single-run --no-colors
104104

105+
106+
echo '---------------------------'
107+
echo '-- E2E TEST: AngularDart --'
108+
echo '---------------------------'
109+
$NGDART_BASE_DIR/scripts/run-e2e-test.sh
110+
111+
105112
echo '-------------------------'
106113
echo '-- DOCS: Generate Docs --'
107114
echo '-------------------------'
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
part of angular.example.animation_spec;
2+
3+
class NgRepeatAppState extends AppState {
4+
var addBtn = element(by.buttonText("Add Thing"));
5+
var removeBtn = element(by.buttonText("Remove Thing"));
6+
var rows = element.all(by.repeater("outer in ctrl.items"));
7+
var thingId = 0; // monotonically increasing.
8+
var things = [];
9+
10+
addThing() {
11+
things.add(thingId++);
12+
addBtn.click();
13+
}
14+
15+
removeThing() {
16+
if (things.length > 0) {
17+
things.removeLast();
18+
}
19+
removeBtn.click();
20+
}
21+
22+
cell(x, y) => rows.get(x).findElements(by.tagName("li"))
23+
.then((e) => toDartArray(e)[y].getText());
24+
25+
assertState() {
26+
expect(rows.count()).toBe(things.length);
27+
for (int y = 0; y < things.length; y++) {
28+
for (int x = 0; x < things.length; x++) {
29+
expect(cell(x, y)).toEqual("Thing ${things[y]}");
30+
}
31+
}
32+
}
33+
}
34+
35+
animation_ng_repeat_spec() {
36+
describe('ng-repeat', () {
37+
var S;
38+
39+
beforeEach(() {
40+
S = new NgRepeatAppState();
41+
S.ngRepeatBtn.click();
42+
});
43+
44+
it('should switch to the ng-repeat example', () {
45+
expect(S.heading.getText()).toEqual("ng-repeat Demo");
46+
S.assertState();
47+
});
48+
49+
it('should add row', () {
50+
S.addThing();
51+
S.assertState();
52+
S.addThing();
53+
S.assertState();
54+
S.removeThing();
55+
S.addThing();
56+
S.assertState();
57+
});
58+
59+
it('should remove rows', () {
60+
S.addThing();
61+
S.addThing();
62+
S.assertState();
63+
64+
S.removeThing();
65+
S.assertState();
66+
67+
S.removeThing();
68+
S.assertState();
69+
});
70+
71+
it('should not remove rows that do not exist', () {
72+
S.removeThing();
73+
S.assertState();
74+
75+
S.addThing();
76+
S.removeThing();
77+
S.removeThing();
78+
S.assertState();
79+
});
80+
81+
it('should add things with monotonically increasing numbers', () {
82+
S.addThing();
83+
S.addThing(); S.removeThing(); S.addThing();
84+
S.addThing(); S.removeThing(); S.addThing();
85+
S.addThing();
86+
expect(S.things).toEqual([0, 2, 4, 5]);
87+
S.assertState();
88+
});
89+
});
90+
}

test_e2e/animation_spec.dart

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
library angular.example.animation_spec;
2+
3+
import 'dart:html';
4+
import 'package:js/js.dart';
5+
import 'package:protractor/protractor_api.dart';
6+
7+
part 'animation_ng_repeat_spec.dart';
8+
part 'animation_visibility_spec.dart';
9+
10+
class AppState {
11+
var ngRepeatBtn = element(by.buttonText("ng-repeat"));
12+
var visibilityBtn = element(by.buttonText("Visibility"));
13+
14+
var heading = element(by.css(".demo h2"));
15+
}
16+
17+
18+
main() {
19+
describe('animation example', () {
20+
beforeEach(() {
21+
protractor.getInstance().get('animation.html');
22+
element(by.tagName("body")).allowAnimations(false);
23+
});
24+
25+
it('should start in about page', () {
26+
var S = new AppState();
27+
expect(S.heading.getText()).toEqual("About");
28+
});
29+
30+
animation_ng_repeat_spec();
31+
animation_visibility_spec();
32+
});
33+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
part of angular.example.animation_spec;
2+
3+
class VisibilityAppState extends AppState {
4+
var toggleBtn = element(by.buttonText("Toggle Visibility"));
5+
var visibleIf = element(by.css(".visible-if"));
6+
var visibleHide = element(by.css(".visible-hide"));
7+
8+
hasClass(var element, String expectedClass) {
9+
return element.getAttribute("class").then((_class) =>
10+
"$_class".split(" ").contains(expectedClass));
11+
}
12+
13+
assertState({bool toggled: false}) {
14+
expect(hasClass(visibleHide, "ng-hide")).toEqual(toggled);
15+
expect(visibleIf.isPresent()).toEqual(toggled);
16+
}
17+
}
18+
19+
animation_visibility_spec() {
20+
var S;
21+
22+
describe('visibility', () {
23+
beforeEach(() {
24+
S = new VisibilityAppState();
25+
S.visibilityBtn.click();
26+
});
27+
28+
it('should switch to the visibility example in initial state', () {
29+
expect(S.heading.getText()).toEqual("Visibility Demo");
30+
expect(S.visibleHide.getText()).toEqual(
31+
"Hello World. ng-hide will add and remove the .ng-hide class "
32+
"from me to show and hide this view of text.");
33+
S.assertState(toggled: false);
34+
});
35+
36+
it('should toggle ng-hide and ng-if', () {
37+
S.toggleBtn.click();
38+
S.assertState(toggled: true);
39+
S.toggleBtn.click();
40+
S.assertState(toggled: false);
41+
S.toggleBtn.click();
42+
S.assertState(toggled: true);
43+
});
44+
45+
});
46+
}

test_e2e/configQuery.js

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
var env = process.env,
2+
fs = require('fs'),
3+
path = require('path');
4+
5+
6+
var runningOnTravis = (env.TRAVIS !== undefined);
7+
8+
9+
function getBaseUrl() {
10+
if (env.NGDART_EXAMPLE_BASEURL) {
11+
return env.NGDART_EXAMPLE_BASEURL;
12+
} else if (env.USER == 'chirayu') {
13+
return 'http://example.ngdart.localhost';
14+
} else {
15+
// Default host:port when you run "pub serve" from the example
16+
// subdirectory of the AngularDart repo.
17+
return 'http://localhost:8080';
18+
}
19+
}
20+
21+
22+
function getDartiumBinary() {
23+
var ensure = function(condition) {
24+
if (!condition) throw "Unable to locate Dartium. Please set the DARTIUM environment variable.";
25+
};
26+
27+
if (env.DARTIUM) {
28+
return env.DARTIUM;
29+
}
30+
var platform = require('os').platform();
31+
var DART_SDK = env.DART_SDK;
32+
if (DART_SDK) {
33+
// Locate the chromium directory as a sibling of the DART_SDK
34+
// directory. (It's there if you unpacked the full Dart distribution.)
35+
var chromiumRoot = path.join(DART_SDK, "../chromium");
36+
ensure(fs.existsSync(chromiumRoot));
37+
var binary = path.join(chromiumRoot,
38+
(platform == 'darwin') ? 'Chromium.app/Contents/MacOS/Chromium' : 'chrome');
39+
ensure(fs.existsSync(binary));
40+
return binary;
41+
}
42+
// Last resort: Try the standard location on Macs for the AngularDart team.
43+
var binary = '/Applications/dart/chromium/Chromium.app/Contents/MacOS/Chromium';
44+
ensure(platform == 'darwin' && fs.existsSync(binary));
45+
return binary;
46+
}
47+
48+
49+
function getChromeOptions() {
50+
if (!runningOnTravis) {
51+
return {'binary': getDartiumBinary()};
52+
}
53+
// In Travis, the list of browsers to test is specified as a CSV in the
54+
// BROWSERS environment variable.
55+
// TODO(chirayu): Parse the BROWSERS csv so we also test on Firefox.
56+
if (env.TESTS == "vm") {
57+
return {'binary': env.DARTIUM_BIN};
58+
}
59+
if (env.TESTS == "dart2js") {
60+
return {
61+
'binary': env.CHROME_BIN,
62+
// Ref: https://github.com/travis-ci/travis-ci/issues/938
63+
// https://sites.google.com/a/chromium.org/chromedriver/help/chrome-doesn-t-start
64+
'args': ['no-sandbox=true']
65+
};
66+
}
67+
throw new Error("Unknown Travis configuration specified by TESTS variable");
68+
}
69+
70+
71+
exports.getBaseUrl = getBaseUrl;
72+
exports.getChromeOptions = getChromeOptions;

0 commit comments

Comments
 (0)