Skip to content

Commit 467ea0f

Browse files
committed
Merge branch 'client-side-tests' into develop
2 parents 9b8b4d8 + 3e3d7e4 commit 467ea0f

File tree

9 files changed

+423
-24
lines changed

9 files changed

+423
-24
lines changed

.editorconfig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[*.js]
2+
indent_style=space
3+
indent_size=4

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,6 @@ nosetests.xml
4141
.pydevproject
4242

4343
.vagrant
44+
45+
# Node
46+
node_modules/

.travis.yml

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,14 @@ python:
66

77
os:
88
- linux
9-
# - osx
9+
10+
addons:
11+
sauce_connect: true
12+
13+
cache:
14+
directories:
15+
- $HOME/.cache/pip
16+
- node_modules
1017

1118
sudo: false
1219

@@ -16,9 +23,15 @@ install:
1623
- pip install git+https://github.com/esnme/ultrajson.git
1724
- python setup.py -q install
1825
- pip install coverage pytest-cov coveralls --use-mirrors
26+
- npm install
27+
28+
before_script:
29+
- export DISPLAY=:99.0
30+
- sh -e /etc/init.d/xvfb start
1931

2032
script:
21-
python setup.py test
33+
- python setup.py test
34+
- cd karma-tests && make test
2235

2336
after_success:
2437
coveralls

karma-tests/Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
NODE_BIN_DIR=../node_modules/.bin
2+
3+
test:
4+
$(NODE_BIN_DIR)/karma start --single-run

karma-tests/dummy.html

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<html>
2+
<head><meta charset="UTF-8"></head>
3+
<body>
4+
<!-- This is a dummy page used in
5+
tests of Wombat's live-rewriting
6+
functionality.
7+
!-->
8+
</body>
9+
</html>

karma-tests/karma.conf.js

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
var sauceLabsConfig = {
2+
testName: 'PyWB Client Tests',
3+
};
4+
5+
// see https://github.com/karma-runner/karma-sauce-launcher/issues/73
6+
if (process.env.TRAVIS_JOB_NUMBER) {
7+
sauceLabsConfig.startConnect = false;
8+
sauceLabsConfig.tunnelIdentifier = process.env.TRAVIS_JOB_NUMBER;
9+
}
10+
11+
var WOMBAT_JS_PATH = 'pywb/static/wombat.js';
12+
13+
var sauceLaunchers = {
14+
sl_chrome: {
15+
base: 'SauceLabs',
16+
browserName: 'chrome',
17+
},
18+
19+
sl_firefox: {
20+
base: 'SauceLabs',
21+
browserName: 'firefox',
22+
},
23+
24+
sl_safari: {
25+
base: 'SauceLabs',
26+
browserName: 'safari',
27+
platform: 'OS X 10.11',
28+
version: '9.0',
29+
},
30+
31+
sl_edge: {
32+
base: 'SauceLabs',
33+
browserName: 'MicrosoftEdge',
34+
},
35+
};
36+
37+
var localLaunchers = {
38+
localFirefox: {
39+
base: 'Firefox',
40+
},
41+
};
42+
43+
var customLaunchers = {};
44+
45+
if (process.env['SAUCE_USERNAME'] && process.env['SAUCE_ACCESS_KEY']) {
46+
customLaunchers = sauceLaunchers;
47+
} else {
48+
console.error('Sauce Labs account details not set, ' +
49+
'Karma tests will be run only against local browsers.' +
50+
'Set SAUCE_USERNAME and SAUCE_ACCESS_KEY environment variables to ' +
51+
'run tests against Sauce Labs browsers');
52+
customLaunchers = localLaunchers;
53+
}
54+
55+
module.exports = function(config) {
56+
config.set({
57+
basePath: '../',
58+
59+
frameworks: ['mocha', 'chai'],
60+
61+
files: [
62+
{
63+
pattern: WOMBAT_JS_PATH,
64+
watched: true,
65+
included: false,
66+
served: true,
67+
},
68+
{
69+
pattern: 'karma-tests/dummy.html',
70+
included: false,
71+
served: true,
72+
},
73+
'karma-tests/*.spec.js',
74+
],
75+
76+
preprocessors: {},
77+
78+
reporters: ['progress'],
79+
80+
port: 9876,
81+
82+
colors: true,
83+
84+
logLevel: config.LOG_INFO,
85+
86+
autoWatch: true,
87+
88+
sauceLabs: sauceLabsConfig,
89+
90+
// Set extended timeouts to account for the slowness
91+
// in connecting to remote browsers (eg. when using
92+
// Sauce Labs)
93+
//
94+
// See https://oligofren.wordpress.com/2014/05/27/running-karma-tests-on-browserstack/
95+
captureTimeout: 3 * 60000,
96+
browserNoActivityTimeout: 30 * 1000,
97+
browserDisconnectTimeout: 10 * 1000,
98+
browserDisconnectTolerance: 1,
99+
100+
customLaunchers: customLaunchers,
101+
102+
browsers: Object.keys(customLaunchers),
103+
104+
singleRun: false,
105+
106+
concurrency: Infinity
107+
})
108+
};

karma-tests/wombat.spec.js

Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
var DEFAULT_TIMEOUT = 20000;
2+
3+
// creates a new document in an <iframe> and runs
4+
// a WombatJS test case in it.
5+
//
6+
// A new <iframe> is used for each test so that each
7+
// case is run with fresh Document and Window objects,
8+
// since Wombat monkey-patches many Document and Window
9+
// functions
10+
//
11+
function runWombatTest(testCase, done) {
12+
// create an <iframe>
13+
var testFrame = document.createElement('iframe');
14+
testFrame.src = '/base/karma-tests/dummy.html';
15+
document.body.appendChild(testFrame);
16+
17+
testFrame.contentWindow.addEventListener('load', function () {
18+
var testDocument = testFrame.contentDocument;
19+
20+
function runFunctionInIFrame(func) {
21+
testFrame.contentWindow.eval('(' + func.toString() + ')()');
22+
}
23+
24+
// expose an error reporting function to the <iframe>
25+
window.reportError = function(ex) {
26+
done(new Error(ex));
27+
};
28+
29+
// expose utility methods for assertion testing in tests.
30+
// (We used to expose chai asserts here but Karma's default
31+
// error reporter replaces URLs in exception messages with
32+
// the corresponding file paths, which is unhelpful for us
33+
// since assert.equal() will often be called with URLs in our tests)
34+
window.assert = {
35+
equal: function (a, b) {
36+
if (a !== b) {
37+
console.error('Mismatch between', a, 'and', b);
38+
throw new Error('AssertionError');
39+
}
40+
}
41+
};
42+
43+
runFunctionInIFrame(function () {
44+
// re-assign the iframe's console object to the parent window's
45+
// console so that messages are intercepted by Karma
46+
// and output to wherever it is configured to send
47+
// console logs (typically stdout)
48+
console = window.parent.console;
49+
window.onerror = function (message, url, line, col, error) {
50+
if (error) {
51+
console.log(error.stack);
52+
}
53+
reportError(new Error(message));
54+
};
55+
56+
// expose chai's assertion testing API to the test script
57+
window.assert = window.parent.assert;
58+
window.reportError = window.parent.reportError;
59+
60+
// helpers which check whether DOM property overrides are supported
61+
// in the current browser
62+
window.domTests = {
63+
areDOMPropertiesConfigurable: function () {
64+
var descriptor = Object.getOwnPropertyDescriptor(Node.prototype, 'baseURI');
65+
if (descriptor && !descriptor.configurable) {
66+
return false;
67+
} else {
68+
return true;
69+
}
70+
}
71+
};
72+
});
73+
74+
try {
75+
runFunctionInIFrame(testCase.initScript);
76+
} catch (e) {
77+
throw new Error('Configuring Wombat failed: ' + e.toString());
78+
}
79+
80+
try {
81+
testFrame.contentWindow.eval(testCase.wombatScript);
82+
runFunctionInIFrame(function () {
83+
new window._WBWombat(wbinfo);
84+
});
85+
} catch (e) {
86+
throw new Error('Initializing WombatJS failed: ' + e.toString());
87+
}
88+
89+
if (testCase.html) {
90+
testDocument.body.innerHTML = testCase.html;
91+
}
92+
93+
if (testCase.testScript) {
94+
try {
95+
runFunctionInIFrame(testCase.testScript);
96+
} catch (e) {
97+
throw new Error('Test script failed: ' + e.toString());
98+
}
99+
}
100+
101+
testFrame.remove();
102+
done();
103+
});
104+
}
105+
106+
describe('WombatJS', function () {
107+
this.timeout(DEFAULT_TIMEOUT);
108+
109+
var wombatScript;
110+
111+
before(function (done) {
112+
// load the source of the WombatJS content
113+
// rewriting script
114+
var req = new XMLHttpRequest();
115+
req.open('GET', '/base/pywb/static/wombat.js');
116+
req.onload = function () {
117+
wombatScript = req.responseText;
118+
done();
119+
};
120+
req.send();
121+
});
122+
123+
it('should load', function (done) {
124+
runWombatTest({
125+
initScript: function () {
126+
wbinfo = {
127+
wombat_opts: {},
128+
};
129+
},
130+
wombatScript: wombatScript,
131+
}, done);
132+
});
133+
134+
describe('anchor rewriting', function () {
135+
var config;
136+
beforeEach(function () {
137+
config = {
138+
initScript: function () {
139+
wbinfo = {
140+
wombat_opts: {},
141+
prefix: window.location.origin,
142+
wombat_ts: '',
143+
};
144+
},
145+
wombatScript: wombatScript,
146+
html: '<a href="foobar.html" id="link">A link</a>',
147+
};
148+
});
149+
150+
it('should rewrite links in dynamically injected <a> tags', function (done) {
151+
config.testScript = function () {
152+
if (domTests.areDOMPropertiesConfigurable()) {
153+
var link = document.getElementById('link');
154+
assert.equal(link.href, 'http:///base/karma-tests/foobar.html');
155+
}
156+
};
157+
158+
runWombatTest(config, done);
159+
});
160+
161+
it('toString() should return the rewritten URL', function (done) {
162+
config.testScript = function () {
163+
if (domTests.areDOMPropertiesConfigurable()) {
164+
var link = document.getElementById('link');
165+
assert.equal(link.href, link.toString());
166+
}
167+
};
168+
runWombatTest(config, done);
169+
});
170+
});
171+
172+
describe('base URL overrides', function () {
173+
it('document.baseURI should return the original URL', function (done) {
174+
runWombatTest({
175+
initScript: function () {
176+
wbinfo = {
177+
wombat_opts: {},
178+
prefix: window.location.origin,
179+
wombat_ts: '',
180+
};
181+
},
182+
wombatScript: wombatScript,
183+
testScript: function () {
184+
var baseURI = document.baseURI;
185+
if (typeof baseURI !== 'string') {
186+
throw new Error('baseURI is not a string');
187+
}
188+
if (domTests.areDOMPropertiesConfigurable()) {
189+
assert.equal(baseURI, 'http:///base/karma-tests/dummy.html');
190+
}
191+
},
192+
}, done);
193+
});
194+
195+
it('should allow base.href to be assigned', function (done) {
196+
runWombatTest({
197+
initScript: function () {
198+
wbinfo = {
199+
wombat_opts: {},
200+
};
201+
},
202+
wombatScript: wombatScript,
203+
testScript: function () {
204+
'use strict';
205+
var baseElement = document.createElement('base');
206+
baseElement.href = 'http://foobar.com/base';
207+
assert.equal(baseElement.href, 'http://foobar.com/base');
208+
},
209+
}, done);
210+
});
211+
});
212+
});

0 commit comments

Comments
 (0)