Skip to content
This repository was archived by the owner on Sep 3, 2024. It is now read-only.

Commit 5a85062

Browse files
committed
add integration tests
(c) Copyright IBM Corp. 2016
1 parent d494ac5 commit 5a85062

File tree

4 files changed

+242
-4
lines changed

4 files changed

+242
-4
lines changed

Makefile

Lines changed: 63 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
# Copyright (c) Jupyter Development Team.
2+
# Distributed under the terms of the Modified BSD License.
3+
4+
.PHONY: help init clean test system-test
5+
16
ROOT_REPO:=jupyter/all-spark-notebook:258e25c03cba
27
CONTAINER_NAME:=declarativewidgets-explorer
38
REPO:=jupyter/declarativewidgets-explorer:258e25c03cba
@@ -40,10 +45,11 @@ node_modules: package.json
4045
bower_components: node_modules bower.json
4146
@npm run bower -- install $(BOWER_OPTS)
4247

48+
run: SERVER_NAME?=urth_explorer_server
4349
run: PORT_MAP?=-p 8888:8888
4450
run: CMD?=jupyter notebook --no-browser --port 8888 --ip="*"
4551
run:
46-
@docker $(DOCKER_OPTS) run --user root $(OPTIONS) \
52+
@docker $(DOCKER_OPTS) run --user root $(OPTIONS) --name $(SERVER_NAME) \
4753
$(PORT_MAP) \
4854
-e USE_HTTP=1 \
4955
-v `pwd`:/srv \
@@ -53,9 +59,63 @@ run:
5359
$(REPO) bash -c '$(CMD)'
5460

5561
test: bower_components
56-
@bower install ../declarativewidgets/elements/urth-core-behaviors/
57-
@bower install ../declarativewidgets/elements/urth-viz-behaviors/
62+
@bower install ../widgets/elements/urth-core-behaviors/
63+
@bower install ../widgets/elements/urth-viz-behaviors/
5864
@npm test
5965

6066
clean:
6167
@-rm -rf bower_components node_modules
68+
69+
### System integration tests
70+
BASEURL?=http://192.168.99.100:8888
71+
BROWSER_LIST?=chrome
72+
TEST_TYPE?=local
73+
SPECS?=system-test/urth-viz-explorer-specs.js
74+
75+
remove-server:
76+
-@docker $(DOCKER_OPTS) rm -f $(SERVER_NAME)
77+
78+
sdist:
79+
80+
run-test: SERVER_NAME?=urth_widgets_integration_test_server
81+
run-test: sdist remove-server
82+
@echo $(TEST_MSG)
83+
@OPTIONS=-d SERVER_NAME=$(SERVER_NAME) $(MAKE) run
84+
@echo 'Waiting for server to start...'
85+
@LIMIT=60; while [ $$LIMIT -gt 0 ] && ! docker logs $(SERVER_NAME) 2>&1 | grep 'Notebook is running'; do echo waiting $$LIMIT...; sleep 1; LIMIT=$$(expr $$LIMIT - 1); done
86+
@$(foreach browser, $(BROWSER_LIST), echo 'Running system integration tests on $(browser)...'; npm run system-test -- $(SPECS) --baseurl $(BASEURL) --test-type $(TEST_TYPE) --browser $(browser) || exit)
87+
@SERVER_NAME=$(SERVER_NAME) $(MAKE) remove-server
88+
89+
system-test-python3: TEST_MSG="Starting system tests for Python 3"
90+
system-test-python3:
91+
TEST_MSG=$(TEST_MSG) TEST_TYPE=$(TEST_TYPE) BROWSER_LIST="$(BROWSER_LIST)" JUPYTER=$(JUPYTER) SPECS="$(SPECS)" BASEURL=$(BASEURL) $(MAKE) run-test
92+
93+
system-test-all: system-test-python3
94+
95+
start-selenium: node_modules stop-selenium
96+
@echo "Installing and starting Selenium Server..."
97+
@node_modules/selenium-standalone/bin/selenium-standalone install >/dev/null
98+
@node_modules/selenium-standalone/bin/selenium-standalone start 2>/dev/null & echo $$! > SELENIUM_PID
99+
100+
stop-selenium:
101+
-@kill `cat SELENIUM_PID`
102+
-@rm SELENIUM_PID
103+
104+
system-test-all-local: TEST_TYPE:="local"
105+
system-test-all-local: start-selenium system-test-all stop-selenium
106+
107+
system-test-all-remote: TEST_TYPE:="remote"
108+
system-test-all-remote: system-test-all
109+
110+
system-test:
111+
ifdef SAUCE_USER_NAME
112+
@echo 'Running system tests on Sauce Labs...'
113+
@BROWSER_LIST="$(BROWSER_LIST)" JUPYTER=$(JUPYTER) SPECS="$(SPECS)" BASEURL=$(BASEURL) $(MAKE) system-test-all-remote
114+
else ifdef TRAVIS
115+
@echo 'Starting system integration tests locally on Travis...'
116+
@BROWSER_LIST="firefox" ALT_BROWSER_LIST="firefox" JUPYTER=$(JUPYTER) SPECS="$(SPECS)" BASEURL=$(BASEURL) $(MAKE) system-test-all-local
117+
else
118+
@echo 'Starting system integration tests locally...'
119+
@BROWSER_LIST="$(BROWSER_LIST)" JUPYTER=$(JUPYTER) SPECS="$(SPECS)" BASEURL=$(BASEURL) $(MAKE) system-test-all-local
120+
endif
121+
@echo 'System integration tests complete.'

package.json

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,21 @@
55
"devDependencies": {
66
"bower": "^1.7.1",
77
"selenium-standalone": "latest",
8+
"mocha" :"^2.0.0",
9+
"wd": "latest",
10+
"chai": "latest",
11+
"chai-as-promised": "latest",
12+
"colors": "latest",
13+
"minimist": "latest",
814
"web-component-tester": "^4",
915
"wct-local": "2.0.3"
1016
},
1117
"config": {},
1218
"scripts": {
1319
"bower": "bower",
1420
"test": "wct test/*",
15-
"test-sauce": "wct --skip-plugin local --plugin sauce test/*"
21+
"test-sauce": "wct --skip-plugin local --plugin sauce test/*",
22+
"system-test": "node_modules/mocha/bin/mocha --timeout 500000 --reporter spec"
1623
},
1724
"repository": {
1825
"type": "git",
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright (c) Jupyter Development Team.
2+
// Distributed under the terms of the Modified BSD License.
3+
4+
var wd = require('wd');
5+
var chai = require('chai');
6+
var Boilerplate = require('./utils/boilerplate');
7+
var boilerplate = new Boilerplate();
8+
9+
describe('Urth Viz Explorer Test', function() {
10+
11+
var tagChaiAssertionError = function(err) {
12+
// throw error and tag as retriable to poll again
13+
err.retriable = err instanceof chai.AssertionError;
14+
throw err;
15+
};
16+
17+
wd.PromiseChainWebdriver.prototype.waitForWidgetElement = function(selector, browserSupportsShadowDOM, timeout, pollFreq) {
18+
return this.waitForElementByCssSelector(
19+
browserSupportsShadowDOM ? 'urth-viz-explorer::shadow urth-viz-vega::shadow svg' : 'urth-viz-explorer urth-viz-vega svg',
20+
wd.asserters.isDisplayed,
21+
timeout)
22+
.catch(tagChaiAssertionError);
23+
};
24+
25+
boilerplate.setup(this.title, '/notebooks/examples/urth-viz-explorer.ipynb');
26+
27+
it('should run all cells and find an explorer in the 5th output area', function(done) {
28+
boilerplate.browser
29+
.waitForElementsByCssSelector('div.output_area').nth(5)
30+
.waitForWidgetElement("urth-viz-explorer", boilerplate.browserSupportsShadowDOM, 10000)
31+
.nodeify(done);
32+
});
33+
34+
it('should have 20 items plotted, by default, then 10 after setting the limit accordingly', function(done) {
35+
boilerplate.browser
36+
.waitForElementsByCssSelector('div.output_area').nth(7)
37+
.moveTo()
38+
.waitForElementsByCssSelector('urth-viz-explorer#v1::shadow urth-viz-vega::shadow svg .marks *', wd.asserters.isDisplayed, 10000)
39+
.should.be.eventually.length(20)
40+
.waitForElementByCssSelector('urth-viz-explorer#v1::shadow #viz-explorer-controls .viz-explorer-controls-section paper-input[label=Limit]::shadow paper-input-container #input', wd.asserters.isDisplayed, 10000)
41+
.click()
42+
.doubleclick()
43+
.type('10')
44+
.sleep(1000)
45+
.elementsByCssSelector('urth-viz-explorer#v1::shadow urth-viz-vega::shadow svg .marks *')
46+
.should.be.eventually.length(10)
47+
.nodeify(done);
48+
});
49+
});

system-test/utils/boilerplate.js

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
// Copyright (c) Jupyter Development Team.
2+
// Distributed under the terms of the Modified BSD License.
3+
4+
var wd = require('wd');
5+
require('colors');
6+
var chai = require('chai');
7+
var chaiAsPromised = require('chai-as-promised');
8+
var parseArgs = require('minimist');
9+
10+
// Parse the args
11+
var args = parseArgs(process.argv);
12+
args.local = args['test-type'] === 'local';
13+
var remote = !args.local;
14+
args.server = args.server || (remote ? 'ondemand.saucelabs.com' : 'localhost:4444');
15+
16+
// Setup chai
17+
chai.use(chaiAsPromised);
18+
chai.should();
19+
chaiAsPromised.transferPromiseness = wd.transferPromiseness;
20+
21+
// Configure webdriver
22+
wd.configureHttp({
23+
timeout: 60000,
24+
retryDelay: 15000,
25+
retries: 5,
26+
baseUrl: args.baseurl
27+
});
28+
29+
// The browser capabilities we would like setup by selenium
30+
var desired = {browserName: 'chrome', platform: 'OS X 10.10'};
31+
if (args.browser && args.browser === 'InternetExplorer') {
32+
args.browser = 'internet explorer';
33+
}
34+
desired.browserName = args.browser || desired.browserName;
35+
desired.platform = args.platform ||
36+
(desired.browserName === 'internet explorer' || desired.browserName === 'MicrosoftEdge') ?
37+
'Windows 10': desired.platform;
38+
desired.tags = ['widgets', 'system-test', desired.browserName];
39+
// If there is a build number, include it in the desired attributes for sauce labs
40+
if (process.env.TRAVIS_JOB_NUMBER) {
41+
desired.tunnelIdentifier = process.env.TRAVIS_JOB_NUMBER;
42+
desired.build = 'widgets-build-' + process.env.TRAVIS_JOB_NUMBER;
43+
}
44+
45+
// The selenium test server, local or remote, we will be using to test against
46+
var testServer = 'http://' + args.server + '/wd/hub';
47+
if (remote) {
48+
testServer = 'http://' + process.env.SAUCE_USERNAME + ':' + process.env.SAUCE_ACCESS_KEY + '@' + args.server + '/wd/hub';
49+
}
50+
51+
console.log('Test server is ', args.server);
52+
console.log('Travis job number is: ', process.env.TRAVIS_JOB_NUMBER);
53+
console.log('Sauce user name is defined? ', !!process.env.SAUCE_USERNAME);
54+
console.log('Sauce access key is defined? ', !!process.env.SAUCE_ACCESS_KEY);
55+
56+
/**
57+
* A helper class to setup webdriver, create a browser, and widget objects for
58+
* use within the system tests.
59+
*/
60+
var Boilerplate = function(){
61+
this.browser = wd.promiseChainRemote(testServer);
62+
this.allPassed = true;
63+
this.SPECIAL_KEYS = wd.SPECIAL_KEYS;
64+
};
65+
66+
/**
67+
* Setups the before and after calls for each of your tests. The boilerplate
68+
* will start each test on startingURL, which is a relative path to the resource to load.
69+
*/
70+
Boilerplate.prototype.setup = function(testName, startingURL){
71+
var that = this;
72+
73+
before(function(done){
74+
if (args.verbose) {
75+
// optional logging
76+
this.browser.on('status', function(info) {
77+
console.log(info.cyan);
78+
});
79+
this.browser.on('command', function(meth, path, data) {
80+
console.log(' > ' + meth.yellow, path.grey, data || '');
81+
});
82+
}
83+
84+
desired.name = testName ? 'Urth Widgets System Test - ' + testName
85+
: 'Urth Widgets System Test';
86+
87+
this.browser.init(desired)
88+
.get(startingURL || '/')
89+
.waitForElementByCssSelector('#kernel_indicator_icon.kernel_idle_icon', wd.asserters.isDisplayed, 10000)
90+
.waitForElementByLinkText('Cell', wd.asserters.isDisplayed, 10000)
91+
.safeExecute('localStorage.clear()')
92+
.elementByLinkText('Cell')
93+
.click()
94+
.waitForElementByLinkText('Run All', wd.asserters.isDisplayed, 10000)
95+
.elementByLinkText('Run All')
96+
.click()
97+
.eval('!!document.body.createShadowRoot', function(err, value) {
98+
this.browserSupportsShadowDOM = value;
99+
}.bind(this))
100+
.waitForElementByCssSelector('div.output_area', wd.asserters.isDisplayed, 10000)
101+
.setAsyncScriptTimeout(15000)
102+
.waitForConditionInBrowser('window.Urth && Urth.kernel && Urth.kernel.is_connected()', 10000)
103+
.waitForElementByCssSelector('#kernel_indicator_icon.kernel_idle_icon', wd.asserters.isDisplayed, 20000)
104+
.waitForConditionInBrowser('typeof Urth.whenReady === "function"', 10000)
105+
.nodeify(done);
106+
}.bind(this));
107+
108+
after(function(done){
109+
var result = this.browser.quit();
110+
if (remote) {
111+
result = result.sauceJobStatus(this.allPassed);
112+
}
113+
result.nodeify(done);
114+
}.bind(this));
115+
116+
afterEach(function(done) {
117+
that.allPassed = that.allPassed && (this.currentTest.state === 'passed');
118+
done();
119+
});
120+
};
121+
122+
module.exports = Boilerplate;

0 commit comments

Comments
 (0)