mirror of
https://github.com/webrecorder/pywb.git
synced 2025-03-15 08:04:49 +01:00
wombat: - I: function overrides applied by wombat now better appear to be the original new function name same as originals when possible - I: WombatLocation now looks and behaves more like the original Location interface - I: The custom storage class now looks and behaves more like the original Storage - I: SVG image rewriting has been improved: both the href and xlink:href deprecated since SVG2 now rewritten always - I: document.open now handles the case of creation of a new window - I: Request object rewriting of the readonly href property is now correctly handled - I: EventTarget.addEventListener, removeEventListener overrides now preserve the original this argument of the wrapped listener - A: document.close override to ensure wombat is initialized after write or writeln usage - A: reconstruction of <doctype...> in rewriteHTMLComplete IFF it was included in the original string of HTML - A: document.body setter override to ensure rewriting of the new body or frameset - A: Attr.[value, nodeValue, textContent] added setter override to perform URL rewrites - A: SVGElements rewriting of the filter, style, xlink:href, href, and src attributes - A: HTMLTrackElement rewriting of the src attribute of the - A: HTMLQuoteElement and HTMLModElement rewriting of the cite attribute - A: Worklet.addModule: Loads JS module specified by a URL. - A: HTMLHyperlinkElementUtils overrides to the areaelement - A: ShadowRootoverrides to: innerHTML even though inherites from DocumentFragement and Node it still has innerHTML getter setter. - A: ShadowRoot, Element, DocumentFragment append, prepend: adds strings of HTML or a new Node inherited from ParentNode - A: StylePropertyMap override: New way to access and set CSS properties. - A: Response.redirecthttps rewriting of the URL argument. - A: UIEvent, MouseEvent, TouchEvent, KeyboardEvent, WheelEvent, InputEvent, and CompositionEven constructor and init{even-name} overrides in order to ensure that wombats JS Proxy usage does not affect their defined behaviors - A: XSLTProcessor override to ensure its usage is not affected by wombats JS Proxy usage. - A: navigator.unregisterProtocolHandler: Same override as existing navigator.registerProtocolHandler but from the inverse operation - A: PresentationRequest: Constructor takes a URL or an array of URLs. - A: EventSource and WebSocket override in order to ensure that they do not cause live leaks - A: overrides for the child node interface - Fix: autofetch worker creatation of the backing worker when it is operating within an execution context with a null origin tests: - A: 559 tests specific to wombat and client side rewritting pywb: - Fix: a few broken tests due to iana.org requiring a user agent in its requests rewrite: - introduced a new JSWorkerRewriter class in order to support rewriting via wombat workers in the context of all supported worker variants via - ensured rewriter app correctly sets the static prefix ci: - Modified travis.yml to specifically enumerate jobs documentation: - Documented new wombat, wombat proxy moded, wombat workers auto-fetch: - switched to mutation observer when in proxy mode so that the behaviors can operate in tandem with the autofetcher
257 lines
7.9 KiB
JavaScript
257 lines
7.9 KiB
JavaScript
import test from 'ava';
|
|
import { URLParts, WB_PREFIX } from './helpers/testedValues';
|
|
import TestHelper from './helpers/testHelper';
|
|
|
|
/**
|
|
* @type {TestHelper}
|
|
*/
|
|
let helper = null;
|
|
|
|
test.before(async t => {
|
|
helper = await TestHelper.init(t);
|
|
await helper.initWombat();
|
|
});
|
|
|
|
test.beforeEach(async t => {
|
|
t.context.sandbox = helper.sandbox();
|
|
t.context.server = helper.server();
|
|
t.context.testPage = helper.testPage();
|
|
});
|
|
|
|
test.afterEach.always(async t => {
|
|
if (t.title.includes('SharedWorker')) {
|
|
await helper.fullRefresh();
|
|
} else {
|
|
await helper.ensureSandbox();
|
|
}
|
|
});
|
|
|
|
test.after.always(async t => {
|
|
await helper.stop();
|
|
});
|
|
|
|
test('The actual top should have been sent the loadMSG', async t => {
|
|
const { testPage, server } = t.context;
|
|
const result = await testPage.evaluate(
|
|
() => window.overwatch.wbMessages.load
|
|
);
|
|
t.true(
|
|
result,
|
|
'The message sent by wombat to inform top it has loaded should have been sent'
|
|
);
|
|
});
|
|
|
|
test('init_top_frame: should set __WB_replay_top correctly', async t => {
|
|
const { sandbox, server } = t.context;
|
|
const result = await sandbox.evaluate(
|
|
() => window.__WB_replay_top === window
|
|
);
|
|
|
|
t.true(result, 'The replay top should equal to frames window object');
|
|
});
|
|
|
|
test('init_top_frame: should set __WB_orig_parent correctly', async t => {
|
|
const { sandbox, server } = t.context;
|
|
const result = await sandbox.evaluate(
|
|
() => window.__WB_orig_parent === window.top
|
|
);
|
|
t.true(result, '__WB_orig_parent should equal the actual top');
|
|
});
|
|
|
|
test('init_top_frame: should set parent to itself (__WB_replay_top)', async t => {
|
|
const { sandbox, server } = t.context;
|
|
const result = await sandbox.evaluate(
|
|
() => window.parent === window.__WB_replay_top
|
|
);
|
|
t.true(result, 'window.parent should equal to itself (__WB_replay_top)');
|
|
});
|
|
|
|
test('WombatLocation: should be added to window as WB_wombat_location', async t => {
|
|
const { sandbox, server } = t.context;
|
|
const result = await sandbox.evaluate(
|
|
() => window.WB_wombat_location != null
|
|
);
|
|
t.true(result, 'WB_wombat_location was not added to window');
|
|
});
|
|
|
|
for (let i = 0; i < URLParts.length; i++) {
|
|
const urlPart = URLParts[i];
|
|
test(`WombatLocation: should make available '${urlPart}'`, async t => {
|
|
const { sandbox, server } = t.context;
|
|
const result = await sandbox.evaluate(
|
|
upart => window.WB_wombat_location[upart] != null,
|
|
urlPart
|
|
);
|
|
t.true(result, `WB_wombat_location does not make available '${urlPart}'`);
|
|
});
|
|
|
|
test(`WombatLocation: the '${urlPart}' property should be equal to the same value as would be returned on the live web`, async t => {
|
|
const { sandbox, server } = t.context;
|
|
const result = await sandbox.evaluate(
|
|
upart =>
|
|
new URL(window.wbinfo.url)[upart] === window.WB_wombat_location[upart],
|
|
urlPart
|
|
);
|
|
t.true(
|
|
result,
|
|
`WB_wombat_location return a value equal to the original for '${urlPart}'`
|
|
);
|
|
});
|
|
}
|
|
|
|
test('WombatLocation: should return the href property as the value for toString', async t => {
|
|
const { sandbox, server } = t.context;
|
|
const result = await sandbox.evaluate(
|
|
() => window.WB_wombat_location.toString() === window.wbinfo.url
|
|
);
|
|
t.true(
|
|
result,
|
|
`WB_wombat_location does not return the href property as the value for toString`
|
|
);
|
|
});
|
|
|
|
test('WombatLocation: should return itself as the value for valueOf', async t => {
|
|
const { sandbox, server } = t.context;
|
|
const result = await sandbox.evaluate(
|
|
() => window.WB_wombat_location.valueOf() === window.WB_wombat_location
|
|
);
|
|
t.true(
|
|
result,
|
|
`WB_wombat_location does not return itself as the value for valueOf`
|
|
);
|
|
});
|
|
|
|
test('WombatLocation: should have a Symbol.toStringTag value of "Location"', async t => {
|
|
const { sandbox, server } = t.context;
|
|
const result = await sandbox.evaluate(
|
|
() =>
|
|
window.WB_wombat_location[window.Symbol.toStringTag] ===
|
|
location[window.Symbol.toStringTag]
|
|
);
|
|
t.true(
|
|
result,
|
|
`WB_wombat_location does not have a Symbol.toStringTag value of "Location"`
|
|
);
|
|
});
|
|
|
|
test('WombatLocation browser navigation control: should rewrite Location.replace usage', async t => {
|
|
const { sandbox, server } = t.context;
|
|
const [navigationResponse] = await Promise.all([
|
|
sandbox.waitForNavigation(),
|
|
sandbox.evaluate(() => {
|
|
window.WB_wombat_location.replace('/it');
|
|
})
|
|
]);
|
|
t.is(
|
|
navigationResponse.url(),
|
|
`${WB_PREFIX}mp_/https://tests.wombat.io/it`,
|
|
'using WB_wombat_location.replace did not navigate the page'
|
|
);
|
|
});
|
|
|
|
test('WombatLocation browser navigation control: should rewrite Location.assign usage', async t => {
|
|
const { sandbox, server } = t.context;
|
|
const [navigationResponse] = await Promise.all([
|
|
sandbox.waitForNavigation(),
|
|
sandbox.evaluate(() => {
|
|
window.WB_wombat_location.assign('/it');
|
|
})
|
|
]);
|
|
t.is(
|
|
navigationResponse.url(),
|
|
`${WB_PREFIX}mp_/https://tests.wombat.io/it`,
|
|
'using WB_wombat_location.assign did not navigate the page'
|
|
);
|
|
});
|
|
|
|
test('WombatLocation browser navigation control: should reload the page via Location.reload usage', async t => {
|
|
const { sandbox, server } = t.context;
|
|
const [originalLoc, navigationResponse] = await Promise.all([
|
|
sandbox.evaluate(() => window.location.href),
|
|
sandbox.waitForNavigation(),
|
|
sandbox.evaluate(() => {
|
|
window.WB_wombat_location.reload();
|
|
})
|
|
]);
|
|
t.is(
|
|
navigationResponse.url(),
|
|
originalLoc,
|
|
'using WB_wombat_location.reload did not reload the page'
|
|
);
|
|
});
|
|
|
|
test('browser history control: should rewrite history.pushState', async t => {
|
|
const { sandbox, server } = t.context;
|
|
const [originalLoc, newloc] = await Promise.all([
|
|
sandbox.evaluate(() => window.location.href),
|
|
sandbox.evaluate(() => {
|
|
window.history.pushState(null, null, '/it');
|
|
return window.location.href;
|
|
})
|
|
]);
|
|
t.is(
|
|
newloc,
|
|
`${originalLoc}it`,
|
|
'history navigations using pushState are not rewritten'
|
|
);
|
|
const result = await sandbox.evaluate(
|
|
() => window.WB_wombat_location.href === 'https://tests.wombat.io/it'
|
|
);
|
|
t.true(
|
|
result,
|
|
'WB_wombat_location.href does not update after history.pushState usage'
|
|
);
|
|
});
|
|
|
|
test('browser history control: should rewrite history.replaceState', async t => {
|
|
const { sandbox, server } = t.context;
|
|
const [originalLoc, newloc] = await Promise.all([
|
|
sandbox.evaluate(() => window.location.href),
|
|
sandbox.evaluate(() => {
|
|
window.history.replaceState(null, null, '/it2');
|
|
return window.location.href;
|
|
})
|
|
]);
|
|
t.is(
|
|
newloc,
|
|
`${originalLoc}it2`,
|
|
'history navigations using pushState are not rewritten'
|
|
);
|
|
const result = await sandbox.evaluate(
|
|
() => window.WB_wombat_location.href === 'https://tests.wombat.io/it2'
|
|
);
|
|
t.true(
|
|
result,
|
|
'WB_wombat_location.href does not update after history.replaceState usage'
|
|
);
|
|
});
|
|
|
|
test('browser history control: should send the "replace-url" msg to the top frame on history.pushState usage', async t => {
|
|
const { sandbox, testPage } = t.context;
|
|
await sandbox.evaluate(() => window.history.pushState(null, null, '/it3'));
|
|
const result = await testPage.evaluate(
|
|
() =>
|
|
window.overwatch.wbMessages['replace-url'].url != null &&
|
|
window.overwatch.wbMessages['replace-url'].url ===
|
|
'https://tests.wombat.io/it3'
|
|
);
|
|
t.true(
|
|
result,
|
|
'the "replace-url" message was not sent to the top frame on history.pushState usage'
|
|
);
|
|
});
|
|
|
|
test('browser history control: should send the "replace-url" msg to the top frame on history.replaceState usage', async t => {
|
|
const { sandbox, testPage } = t.context;
|
|
await sandbox.evaluate(() => window.history.replaceState(null, null, '/it4'));
|
|
t.true(
|
|
await testPage.evaluate(
|
|
() =>
|
|
window.overwatch.wbMessages['replace-url'].url != null &&
|
|
window.overwatch.wbMessages['replace-url'].url ===
|
|
'https://tests.wombat.io/it4'
|
|
),
|
|
'the "replace-url" message was not sent to the top frame on history.pushState usage'
|
|
);
|
|
});
|