1
0
mirror of https://github.com/webrecorder/pywb.git synced 2025-03-24 06:59:52 +01:00

Merge pull request #157 from robertknight/wombat-ms-edge-compat

Microsoft Edge compatibility fixes, including Safari fix from #156 and Node.prototype fix from #154
This commit is contained in:
Ilya Kreymer 2015-11-26 10:11:21 -08:00
commit b3c9a47ec7
5 changed files with 150 additions and 63 deletions

View File

@ -7,6 +7,9 @@ python:
os: os:
- linux - linux
addons:
sauce_connect: true
cache: cache:
directories: directories:
- $HOME/.cache/pip - $HOME/.cache/pip
@ -22,6 +25,10 @@ install:
- pip install coverage pytest-cov coveralls --use-mirrors - pip install coverage pytest-cov coveralls --use-mirrors
- npm install - npm install
before_script:
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start
script: script:
- python setup.py test - python setup.py test
- cd karma-tests && make test - cd karma-tests && make test

9
karma-tests/dummy.html Normal file
View File

@ -0,0 +1,9 @@
<html>
<head><meta charset="UTF-8"></head>
<body>
<!-- This is a dummy page used in
tests of Wombat's live-rewriting
functionality.
!-->
</body>
</html>

View File

@ -1,8 +1,3 @@
if (!process.env['SAUCE_USERNAME'] || !process.env['SAUCE_ACCESS_KEY']) {
console.error('Sauce Labs account details not set, skipping Karma tests');
process.exit(0);
}
var sauceLabsConfig = { var sauceLabsConfig = {
testName: 'PyWB Client Tests', testName: 'PyWB Client Tests',
}; };
@ -15,7 +10,7 @@ if (process.env.TRAVIS_JOB_NUMBER) {
var WOMBAT_JS_PATH = 'pywb/static/wombat.js'; var WOMBAT_JS_PATH = 'pywb/static/wombat.js';
var customLaunchers = { var sauceLaunchers = {
sl_chrome: { sl_chrome: {
base: 'SauceLabs', base: 'SauceLabs',
browserName: 'chrome', browserName: 'chrome',
@ -26,25 +21,37 @@ var customLaunchers = {
browserName: 'firefox', browserName: 'firefox',
}, },
/* Safari and Edge are currently broken in
pywb.
See: https://github.com/ikreymer/pywb/issues/148 (Edge)
https://github.com/ikreymer/pywb/issues/147 (Safari)
sl_safari: { sl_safari: {
base: 'SauceLabs', base: 'SauceLabs',
browserName: 'safari', browserName: 'safari',
platform: 'OS X 10.11', platform: 'OS X 10.11',
version: '9.0', version: '9.0',
}, },
sl_edge: { sl_edge: {
base: 'SauceLabs', base: 'SauceLabs',
browserName: 'MicrosoftEdge', browserName: 'MicrosoftEdge',
}, },
*/
}; };
var localLaunchers = {
localFirefox: {
base: 'Firefox',
},
};
var customLaunchers = {};
if (process.env['SAUCE_USERNAME'] && process.env['SAUCE_ACCESS_KEY']) {
customLaunchers = sauceLaunchers;
} else {
console.error('Sauce Labs account details not set, ' +
'Karma tests will be run only against local browsers.' +
'Set SAUCE_USERNAME and SAUCE_ACCESS_KEY environment variables to ' +
'run tests against Sauce Labs browsers');
customLaunchers = localLaunchers;
}
module.exports = function(config) { module.exports = function(config) {
config.set({ config.set({
basePath: '../', basePath: '../',
@ -58,6 +65,11 @@ module.exports = function(config) {
included: false, included: false,
served: true, served: true,
}, },
{
pattern: 'karma-tests/dummy.html',
included: false,
served: true,
},
'karma-tests/*.spec.js', 'karma-tests/*.spec.js',
], ],
@ -75,9 +87,15 @@ module.exports = function(config) {
sauceLabs: sauceLabsConfig, sauceLabs: sauceLabsConfig,
// use an extended timeout for capturing Sauce Labs // Set extended timeouts to account for the slowness
// browsers in case the service is busy // in connecting to remote browsers (eg. when using
// Sauce Labs)
//
// See https://oligofren.wordpress.com/2014/05/27/running-karma-tests-on-browserstack/
captureTimeout: 3 * 60000, captureTimeout: 3 * 60000,
browserNoActivityTimeout: 30 * 1000,
browserDisconnectTimeout: 10 * 1000,
browserDisconnectTolerance: 1,
customLaunchers: customLaunchers, customLaunchers: customLaunchers,

View File

@ -1,4 +1,3 @@
var WOMBAT_SRC = '../pywb/static/wombat.js';
var DEFAULT_TIMEOUT = 20000; var DEFAULT_TIMEOUT = 20000;
// creates a new document in an <iframe> and runs // creates a new document in an <iframe> and runs
@ -12,7 +11,7 @@ var DEFAULT_TIMEOUT = 20000;
function runWombatTest(testCase, done) { function runWombatTest(testCase, done) {
// create an <iframe> // create an <iframe>
var testFrame = document.createElement('iframe'); var testFrame = document.createElement('iframe');
testFrame.src = '/dummy.html'; testFrame.src = '/base/karma-tests/dummy.html';
document.body.appendChild(testFrame); document.body.appendChild(testFrame);
testFrame.contentWindow.addEventListener('load', function () { testFrame.contentWindow.addEventListener('load', function () {
@ -27,8 +26,20 @@ function runWombatTest(testCase, done) {
done(new Error(ex)); done(new Error(ex));
}; };
// expose chai assertions to the <iframe> // expose utility methods for assertion testing in tests.
window.assert = assert; // (We used to expose chai asserts here but Karma's default
// error reporter replaces URLs in exception messages with
// the corresponding file paths, which is unhelpful for us
// since assert.equal() will often be called with URLs in our tests)
window.assert = {
equal: function (a, b) {
if (a !== b) {
x.equal(a, b);
console.error('Mismatch between', a, 'and', b);
throw new Error('AssertionError');
}
}
};
runFunctionInIFrame(function () { runFunctionInIFrame(function () {
// re-assign the iframe's console object to the parent window's // re-assign the iframe's console object to the parent window's
@ -44,8 +55,21 @@ function runWombatTest(testCase, done) {
}; };
// expose chai's assertion testing API to the test script // expose chai's assertion testing API to the test script
assert = window.parent.assert; window.assert = window.parent.assert;
reportError = window.parent.reportError; window.reportError = window.parent.reportError;
// helpers which check whether DOM property overrides are supported
// in the current browser
window.domTests = {
areDOMPropertiesConfigurable: function () {
var descriptor = Object.getOwnPropertyDescriptor(Node.prototype, 'baseURI');
if (descriptor && !descriptor.configurable) {
return false;
} else {
return true;
}
}
};
}); });
try { try {
@ -108,41 +132,66 @@ describe('WombatJS', function () {
}, done); }, done);
}); });
it('should rewrite document.baseURI', function (done) { describe('anchor rewriting', function () {
runWombatTest({ it('should rewrite links in dynamically injected <a> tags', function (done) {
initScript: function () { runWombatTest({
wbinfo = { initScript: function () {
wombat_opts: {}, wbinfo = {
prefix: window.location.origin, wombat_opts: {},
wombat_ts: '', prefix: window.location.origin,
}; wombat_ts: '',
}, };
wombatScript: wombatScript, },
testScript: function () { wombatScript: wombatScript,
var baseURI = document.baseURI; html: '<a href="foobar.html" id="link">A link</a>',
if (typeof baseURI !== 'string') { testScript: function () {
throw new Error('baseURI is not a string'); var link = document.getElementById('link');
} if (domTests.areDOMPropertiesConfigurable()) {
assert.equal(baseURI, 'http:///dummy.html'); assert.equal(link.href, 'http:///base/karma-tests/foobar.html');
}, }
}, done); },
}, done);
});
}); });
it('should rewrite links in dynamically injected <a> tags', function (done) { describe('base URL overrides', function () {
runWombatTest({ it('document.baseURI should return the original URL', function (done) {
initScript: function () { runWombatTest({
wbinfo = { initScript: function () {
wombat_opts: {}, wbinfo = {
prefix: window.location.origin, wombat_opts: {},
wombat_ts: '', prefix: window.location.origin,
}; wombat_ts: '',
}, };
wombatScript: wombatScript, },
html: '<a href="foobar.html" id="link">A link</a>', wombatScript: wombatScript,
testScript: function () { testScript: function () {
var link = document.getElementById('link'); var baseURI = document.baseURI;
assert.equal(link.href, 'http:///foobar.html'); if (typeof baseURI !== 'string') {
}, throw new Error('baseURI is not a string');
}, done); }
if (domTests.areDOMPropertiesConfigurable()) {
assert.equal(baseURI, 'http:///base/karma-tests/dummy.html');
}
},
}, done);
});
it('should allow base.href to be assigned', function (done) {
runWombatTest({
initScript: function () {
wbinfo = {
wombat_opts: {},
};
},
wombatScript: wombatScript,
testScript: function () {
'use strict';
var baseElement = document.createElement('base');
baseElement.href = 'http://foobar.com/base';
assert.equal(baseElement.href, 'http://foobar.com/base');
},
}, done);
});
}); });
}); });

View File

@ -379,11 +379,16 @@ var wombat_internal = function($wbwindow) {
} }
try { try {
Object.defineProperty(obj, prop, { var descriptor = {
configurable: false, configurable: true,
set: set_func, get: get_func,
get: get_func };
});
if (set_func) {
descriptor.set = set_func;
}
Object.defineProperty(obj, prop, descriptor);
return true; return true;
} catch (e) { } catch (e) {
@ -762,15 +767,14 @@ var wombat_internal = function($wbwindow) {
def_prop($wbwindow.HTMLBaseElement.prototype, "href", undefined, base_href_get); def_prop($wbwindow.HTMLBaseElement.prototype, "href", undefined, base_href_get);
// Shared baseURI // Shared baseURI
var orig_getter = get_orig_getter($wbwindow.Node, "baseURI"); var orig_getter = get_orig_getter($wbwindow.Node.prototype, "baseURI");
if (orig_getter) { if (orig_getter) {
var get_baseURI = function() { var get_baseURI = function() {
var res = orig_getter.call(this); var res = orig_getter.call(this);
return extract_orig(res); return extract_orig(res);
} }
def_prop($wbwindow.HTMLElement.prototype, "baseURI", undefined, get_baseURI); def_prop($wbwindow.Node.prototype, "baseURI", undefined, get_baseURI);
def_prop($wbwindow.HTMLDocument.prototype, "baseURI", undefined, get_baseURI);
} }
} }