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
558 lines
19 KiB
JavaScript
558 lines
19 KiB
JavaScript
import test from 'ava';
|
|
import TestHelper from './helpers/testHelper';
|
|
import * as testedChanges from './helpers/testedValues';
|
|
|
|
/**
|
|
* @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.testPage = helper.testPage();
|
|
t.context.server = helper.server();
|
|
});
|
|
|
|
test.after.always(async t => {
|
|
await helper.stop();
|
|
});
|
|
|
|
test('internal globals: should not have removed _WBWombat from window', async t => {
|
|
const { sandbox, server } = t.context;
|
|
t.deepEqual(
|
|
await sandbox.evaluate(() => ({
|
|
_WBWombat: {
|
|
exists: window._WBWombat != null,
|
|
type: typeof window._WBWombat
|
|
},
|
|
_WBWombatInit: {
|
|
exists: window._WBWombatInit != null,
|
|
type: typeof window._WBWombatInit
|
|
}
|
|
})),
|
|
{
|
|
_WBWombat: { exists: true, type: 'function' },
|
|
_WBWombatInit: { exists: true, type: 'function' }
|
|
},
|
|
'The internal globals _WBWombat and _WBWombatInit are not as expected after initialization'
|
|
);
|
|
});
|
|
|
|
test('internal globals: should add the property __WB_replay_top to window that is equal to the same window', async t => {
|
|
const { sandbox, server } = t.context;
|
|
t.deepEqual(
|
|
await sandbox.evaluate(() => ({
|
|
exists: window.__WB_replay_top != null,
|
|
eq: window.__WB_replay_top === window
|
|
})),
|
|
{
|
|
exists: true,
|
|
eq: true
|
|
},
|
|
'The internal global __WB_replay_top is not as expected after initialization'
|
|
);
|
|
});
|
|
|
|
test('internal globals: should define the property __WB_top_frame when it is the top replayed page', async t => {
|
|
const { sandbox, server } = t.context;
|
|
t.deepEqual(
|
|
await sandbox.evaluate(() => ({
|
|
exists: window.__WB_top_frame != null,
|
|
neq: window.__WB_top_frame !== window
|
|
})),
|
|
{
|
|
exists: true,
|
|
neq: true
|
|
},
|
|
'The internal global __WB_top_frame is not as expected after initialization'
|
|
);
|
|
});
|
|
|
|
test('internal globals: should define the WB_wombat_top property on Object.prototype', async t => {
|
|
const { sandbox, server } = t.context;
|
|
t.deepEqual(
|
|
await sandbox.evaluate(() => {
|
|
const descriptor = Reflect.getOwnPropertyDescriptor(
|
|
Object.prototype,
|
|
'WB_wombat_top'
|
|
);
|
|
if (!descriptor) return { exists: false };
|
|
return {
|
|
exists: true,
|
|
configurable: descriptor.configurable,
|
|
enumerable: descriptor.enumerable,
|
|
get: typeof descriptor.get,
|
|
set: typeof descriptor.set
|
|
};
|
|
}),
|
|
{
|
|
exists: true,
|
|
configurable: true,
|
|
enumerable: false,
|
|
get: 'function',
|
|
set: 'function'
|
|
},
|
|
'The property descriptor added to the prototype of Object for WB_wombat_top is not correct'
|
|
);
|
|
});
|
|
|
|
test('internal globals: should add the _WB_wombat_location property to window', async t => {
|
|
const { sandbox, server } = t.context;
|
|
t.deepEqual(
|
|
await sandbox.evaluate(() => ({
|
|
_WB_wombat_location: {
|
|
exists: window._WB_wombat_location != null,
|
|
type: typeof window._WB_wombat_location
|
|
},
|
|
WB_wombat_location: {
|
|
exists: window.WB_wombat_location != null,
|
|
type: typeof window.WB_wombat_location
|
|
}
|
|
})),
|
|
{
|
|
_WB_wombat_location: { exists: true, type: 'object' },
|
|
WB_wombat_location: { exists: true, type: 'object' }
|
|
},
|
|
'Wombat location properties on window are not correct'
|
|
);
|
|
});
|
|
|
|
test('internal globals: should add the __wb_Date_now property to window', async t => {
|
|
const { sandbox, server } = t.context;
|
|
t.deepEqual(
|
|
await sandbox.evaluate(() => ({
|
|
exists: window.__wb_Date_now != null,
|
|
type: typeof window.__wb_Date_now
|
|
})),
|
|
{ exists: true, type: 'function' },
|
|
'The __wb_Date_now property of window is incorrect'
|
|
);
|
|
});
|
|
|
|
test('internal globals: should add the __WB_timediff property to window.Date', async t => {
|
|
const { sandbox, server } = t.context;
|
|
t.deepEqual(
|
|
await sandbox.evaluate(() => ({
|
|
exists: window.Date.__WB_timediff != null,
|
|
type: typeof window.Date.__WB_timediff
|
|
})),
|
|
{ exists: true, type: 'number' },
|
|
'The __WB_timediff property of window.Date is incorrect'
|
|
);
|
|
});
|
|
|
|
test('internal globals: should persist the original window.postMessage as __orig_postMessage', async t => {
|
|
const { sandbox, server } = t.context;
|
|
t.deepEqual(
|
|
await sandbox.evaluate(() => ({
|
|
exists: window.__orig_postMessage != null,
|
|
type: typeof window.__orig_postMessage,
|
|
isO: window.__orig_postMessage.toString().includes('[native code]')
|
|
})),
|
|
{ exists: true, type: 'function', isO: true },
|
|
'The __WB_timediff property of window.Date is incorrect'
|
|
);
|
|
});
|
|
|
|
test('internal globals: should not expose WombatLocation on window', async t => {
|
|
const { sandbox, server } = t.context;
|
|
t.true(
|
|
await sandbox.evaluate(() => !('WombatLocation' in window)),
|
|
'WombatLocation should not be exposed directly'
|
|
);
|
|
});
|
|
|
|
test('exposed functions - extract_orig: should should extract the original url', async t => {
|
|
const { sandbox, server } = t.context;
|
|
t.true(
|
|
await sandbox.evaluate(
|
|
() =>
|
|
window._wb_wombat.extract_orig(
|
|
'http://localhost:3030/jberlin/sw/20180510171123/https://n0tan3rd.github.io/replay_test/'
|
|
) === 'https://n0tan3rd.github.io/replay_test/'
|
|
),
|
|
'extract_orig could not extract the original URL'
|
|
);
|
|
});
|
|
|
|
test('exposed functions - extract_orig: should not modify an un-rewritten url', async t => {
|
|
const { sandbox, server } = t.context;
|
|
t.true(
|
|
await sandbox.evaluate(
|
|
() =>
|
|
window._wb_wombat.extract_orig(
|
|
'https://n0tan3rd.github.io/replay_test/'
|
|
) === 'https://n0tan3rd.github.io/replay_test/'
|
|
),
|
|
'extract_orig modified an original URL'
|
|
);
|
|
});
|
|
|
|
test('exposed functions - extract_orig: should be able to extract the original url from an encoded string', async t => {
|
|
const { sandbox, server } = t.context;
|
|
t.deepEqual(
|
|
await sandbox.evaluate(() => {
|
|
const expected = 'https://n0tan3rd.github.io/replay_test/';
|
|
const extractO = window._wb_wombat.extract_orig;
|
|
const unicode = extractO(
|
|
'\u0068\u0074\u0074\u0070\u003a\u002f\u002f\u006c\u006f\u0063\u0061\u006c\u0068\u006f\u0073\u0074\u003a\u0033\u0030\u0033\u0030\u002f\u006a\u0062\u0065\u0072\u006c\u0069\u006e\u002f\u0073\u0077\u002f\u0032\u0030\u0031\u0038\u0030\u0035\u0031\u0030\u0031\u0037\u0031\u0031\u0032\u0033\u002f\u0068\u0074\u0074\u0070\u0073\u003a\u002f\u002f\u006e\u0030\u0074\u0061\u006e\u0033\u0072\u0064\u002e\u0067\u0069\u0074\u0068\u0075\u0062\u002e\u0069\u006f\u002f\u0072\u0065\u0070\u006c\u0061\u0079\u005f\u0074\u0065\u0073\u0074\u002f'
|
|
);
|
|
const hex = extractO(
|
|
'\x68\x74\x74\x70\x3a\x2f\x2f\x6c\x6f\x63\x61\x6c\x68\x6f\x73\x74\x3a\x33\x30\x33\x30\x2f\x6a\x62\x65\x72\x6c\x69\x6e\x2f\x73\x77\x2f\x32\x30\x31\x38\x30\x35\x31\x30\x31\x37\x31\x31\x32\x33\x2f\x68\x74\x74\x70\x73\x3a\x2f\x2f\x6e\x30\x74\x61\x6e\x33\x72\x64\x2e\x67\x69\x74\x68\x75\x62\x2e\x69\x6f\x2f\x72\x65\x70\x6c\x61\x79\x5f\x74\x65\x73\x74\x2f'
|
|
);
|
|
return {
|
|
unicode:
|
|
unicode === expected &&
|
|
unicode ===
|
|
'\u0068\u0074\u0074\u0070\u0073\u003a\u002f\u002f\u006e\u0030\u0074\u0061\u006e\u0033\u0072\u0064\u002e\u0067\u0069\u0074\u0068\u0075\u0062\u002e\u0069\u006f\u002f\u0072\u0065\u0070\u006c\u0061\u0079\u005f\u0074\u0065\u0073\u0074\u002f',
|
|
hex:
|
|
hex === expected &&
|
|
hex ===
|
|
'\x68\x74\x74\x70\x73\x3a\x2f\x2f\x6e\x30\x74\x61\x6e\x33\x72\x64\x2e\x67\x69\x74\x68\x75\x62\x2e\x69\x6f\x2f\x72\x65\x70\x6c\x61\x79\x5f\x74\x65\x73\x74\x2f'
|
|
};
|
|
}),
|
|
{ unicode: true, hex: true },
|
|
'extract_orig could not extract the original URL from an encoded string'
|
|
);
|
|
});
|
|
|
|
test('exposed functions - rewrite_url: should be able to rewrite an encoded string', async t => {
|
|
const { sandbox, server } = t.context;
|
|
t.deepEqual(
|
|
await sandbox.evaluate(() => {
|
|
const expected = 'https://n0tan3rd.github.io/replay_test/';
|
|
const rewrite_url = window._wb_wombat.rewrite_url;
|
|
const unicode = rewrite_url(
|
|
'\u0068\u0074\u0074\u0070\u0073\u003a\u002f\u002f\u006e\u0030\u0074\u0061\u006e\u0033\u0072\u0064\u002e\u0067\u0069\u0074\u0068\u0075\u0062\u002e\u0069\u006f\u002f\u0072\u0065\u0070\u006c\u0061\u0079\u005f\u0074\u0065\u0073\u0074\u002f'
|
|
);
|
|
const hex = rewrite_url(
|
|
'\x68\x74\x74\x70\x73\x3a\x2f\x2f\x6e\x30\x74\x61\x6e\x33\x72\x64\x2e\x67\x69\x74\x68\x75\x62\x2e\x69\x6f\x2f\x72\x65\x70\x6c\x61\x79\x5f\x74\x65\x73\x74\x2f'
|
|
);
|
|
return {
|
|
unicode:
|
|
unicode ===
|
|
`${window.wbinfo.prefix}${window.wbinfo.wombat_ts}${
|
|
window.wbinfo.mod
|
|
}/${expected}`,
|
|
hex:
|
|
hex ===
|
|
`${window.wbinfo.prefix}${window.wbinfo.wombat_ts}${
|
|
window.wbinfo.mod
|
|
}/${expected}`
|
|
};
|
|
}),
|
|
{ unicode: true, hex: true },
|
|
'rewrite_url could not rewrite an encoded string'
|
|
);
|
|
});
|
|
|
|
testedChanges.TestedPropertyDescriptorUpdates.forEach(aTest => {
|
|
const msg = 'an property descriptor override should have been applied';
|
|
aTest.props.forEach(prop => {
|
|
if (aTest.docOrWin) {
|
|
test(`${aTest.docOrWin}.${prop}: ${msg}`, async t => {
|
|
const { sandbox, server } = t.context;
|
|
const result = await sandbox.evaluate(
|
|
testFn,
|
|
aTest.docOrWin,
|
|
prop,
|
|
aTest.expectedInterface,
|
|
aTest.skipGet,
|
|
aTest.skipSet
|
|
);
|
|
t.deepEqual(
|
|
result.main,
|
|
{ exists: true, good: true },
|
|
`The property descriptor for ${aTest.docOrWin}.${prop} is incorrect`
|
|
);
|
|
for (let i = 0; i < result.sub.length; i++) {
|
|
const subTest = result.sub[i];
|
|
t.true(subTest.result, subTest.what);
|
|
}
|
|
});
|
|
} else if (aTest.objPaths) {
|
|
aTest.objPaths.forEach(objPath => {
|
|
test(`${objPath.replace('window.', '')}.${prop}: ${msg}`, async t => {
|
|
const { sandbox, server } = t.context;
|
|
const result = await sandbox.evaluate(
|
|
testFn,
|
|
objPath,
|
|
prop,
|
|
aTest.expectedInterface,
|
|
aTest.skipGet,
|
|
aTest.skipSet
|
|
);
|
|
t.deepEqual(
|
|
result.main,
|
|
{ exists: true, good: true },
|
|
`The property descriptor for ${objPath.replace(
|
|
'window.',
|
|
''
|
|
)}.${prop} is incorrect`
|
|
);
|
|
for (let i = 0; i < result.sub.length; i++) {
|
|
const subTest = result.sub[i];
|
|
t.true(subTest.result, subTest.what);
|
|
}
|
|
});
|
|
});
|
|
} else {
|
|
test(`${aTest.objPath.replace(
|
|
'window.',
|
|
''
|
|
)}.${prop}: ${msg}`, async t => {
|
|
const { sandbox, server } = t.context;
|
|
const result = await sandbox.evaluate(
|
|
testFn,
|
|
aTest.objPath,
|
|
prop,
|
|
aTest.expectedInterface,
|
|
aTest.skipGet,
|
|
aTest.skipSet
|
|
);
|
|
t.deepEqual(
|
|
result.main,
|
|
{ exists: true, good: true },
|
|
`The property descriptor for ${aTest.objPath.replace(
|
|
'window.',
|
|
''
|
|
)}.prop is incorrect`
|
|
);
|
|
for (let i = 0; i < result.sub.length; i++) {
|
|
const subTest = result.sub[i];
|
|
t.true(subTest.result, subTest.what);
|
|
}
|
|
});
|
|
}
|
|
});
|
|
function testFn(objectPath, prop, expectedInterface, skipGet, skipSet) {
|
|
// get the original and wombat object represented by the object path expression
|
|
// eg if objectPath is window.Node.prototype then original === window.Node.prototype and obj === wombatSandbox.window.Node.prototype
|
|
const original = window.WombatTestUtil.getOriginalWinDomViaPath(objectPath);
|
|
const existing = window.WombatTestUtil.getViaPath(
|
|
window.wombatSandbox,
|
|
objectPath
|
|
);
|
|
// sometimes we need to skip a property get/set toString check
|
|
let skipGetCheck = !!(skipGet && skipGet.indexOf(prop) > -1);
|
|
let skipSetCheck = !!(skipSet && skipSet.indexOf(prop) > -1);
|
|
// use the reflect object in the wombat sandbox context
|
|
const newPD = Reflect.getOwnPropertyDescriptor(existing, prop);
|
|
const expectedEntries = Object.entries(expectedInterface);
|
|
const tResults = {
|
|
main: {
|
|
exists: newPD != null,
|
|
good: expectedEntries.every(([pk, ptype]) => typeof newPD[pk] === ptype)
|
|
},
|
|
sub: []
|
|
};
|
|
const originalPD = window.WombatTestUtil.getOriginalPropertyDescriptorFor(
|
|
original,
|
|
prop
|
|
);
|
|
if (originalPD) {
|
|
// do a quick deep check first to see if we modified something
|
|
tResults.sub.push({
|
|
what: 'newPD !== originalPD',
|
|
result: expectedEntries.some(
|
|
([pk, ptype]) => newPD[pk] !== originalPD[pk]
|
|
)
|
|
});
|
|
// now check each part of the expected property descriptor to make sure nothing went wrong
|
|
if (
|
|
!skipGetCheck &&
|
|
expectedInterface.get &&
|
|
newPD.get &&
|
|
originalPD.get
|
|
) {
|
|
tResults.sub.push({
|
|
what: `${objectPath}.${prop} getter.toString() !== original getter.toString()`,
|
|
result: newPD.get.toString() !== originalPD.get.toString()
|
|
});
|
|
}
|
|
if (
|
|
!skipSetCheck &&
|
|
expectedInterface.set &&
|
|
newPD.set &&
|
|
originalPD.set
|
|
) {
|
|
tResults.sub.push({
|
|
what: `${objectPath}.${prop} setter.toString() !== original setter.toString()`,
|
|
result: newPD.set.toString() !== originalPD.set.toString()
|
|
});
|
|
}
|
|
if (originalPD.configurable != null && newPD.configurable != null) {
|
|
tResults.sub.push({
|
|
what: `${objectPath}.${prop} the "new" configurable pd does not equals the original`,
|
|
result: newPD.configurable === originalPD.configurable
|
|
});
|
|
}
|
|
if (originalPD.writable != null && newPD.writable != null) {
|
|
tResults.sub.push({
|
|
what: `${objectPath}.${prop} the "new" writable pd does not equals the original`,
|
|
result: newPD.writable === originalPD.writable
|
|
});
|
|
}
|
|
if (originalPD.value != null && newPD.value != null) {
|
|
tResults.sub.push({
|
|
what: `${objectPath}.${prop} the "new" value pd does equals the original`,
|
|
result: newPD.value !== originalPD.value
|
|
});
|
|
}
|
|
}
|
|
return tResults;
|
|
}
|
|
});
|
|
|
|
testedChanges.TestFunctionChanges.forEach(aTest => {
|
|
if (aTest.constructors) {
|
|
aTest.constructors.forEach(ctor => {
|
|
const niceC = ctor.replace('window.', '');
|
|
test(`${niceC}: an constructor override should have been applied`, async t => {
|
|
const { sandbox, server } = t.context;
|
|
t.true(
|
|
await sandbox.evaluate(testFN, ctor),
|
|
`The ${ctor} was not updated`
|
|
);
|
|
function testFN(ctor) {
|
|
const existing = window.WombatTestUtil.getViaPath(
|
|
window.wombatSandbox,
|
|
ctor
|
|
);
|
|
const original = window.WombatTestUtil.getOriginalWinDomViaPath(ctor);
|
|
return existing.toString() !== original.toString();
|
|
}
|
|
});
|
|
});
|
|
} else if (aTest.objPath && aTest.origs) {
|
|
for (let i = 0; i < aTest.fns.length; i++) {
|
|
const fn = aTest.fns[i];
|
|
const ofn = aTest.origs[i];
|
|
const niceWhat = `${aTest.objPath.replace('window.', '')}.${fn}`;
|
|
test(`${niceWhat}: an function override should have been applied`, async t => {
|
|
const { sandbox, server } = t.context;
|
|
t.deepEqual(
|
|
await sandbox.evaluate(testFN, aTest.objPath, fn, ofn),
|
|
{ ne: true, persisted: true },
|
|
`The ${niceWhat} was not updated correctly`
|
|
);
|
|
function testFN(objPath, fn, ofn) {
|
|
const existing = window.WombatTestUtil.getViaPath(
|
|
window.wombatSandbox,
|
|
objPath
|
|
);
|
|
const original = window.WombatTestUtil.getOriginalWinDomViaPath(
|
|
objPath
|
|
);
|
|
return {
|
|
ne: existing[fn].toString() !== original[fn].toString(),
|
|
persisted: existing[ofn].toString() === original[fn].toString()
|
|
};
|
|
}
|
|
});
|
|
}
|
|
} else if (aTest.fnPath) {
|
|
test(`${
|
|
aTest.fnPath
|
|
}: an function override should have been applied`, async t => {
|
|
const { sandbox, server } = t.context;
|
|
const result = await sandbox.evaluate(testFN, aTest.fnPath, aTest.oPath);
|
|
t.true(result.ne, `${aTest.fnPath} was not updated`);
|
|
if (result.originalPersisted) {
|
|
t.true(
|
|
result.originalPersisted,
|
|
`The persisted original function for ${
|
|
aTest.fnPath
|
|
} does not match the original`
|
|
);
|
|
}
|
|
function testFN(fnPath, oPath) {
|
|
const existing = window.WombatTestUtil.getViaPath(
|
|
window.wombatSandbox,
|
|
fnPath
|
|
);
|
|
const original = window.WombatTestUtil.getOriginalWinDomViaPath(fnPath);
|
|
const result = {
|
|
ne: existing.toString() !== original.toString()
|
|
};
|
|
if (oPath) {
|
|
const ofnOnfn = window.WombatTestUtil.getViaPath(
|
|
window.wombatSandbox,
|
|
oPath
|
|
);
|
|
result.originalPersisted = ofnOnfn.toString() === original.toString();
|
|
}
|
|
return result;
|
|
}
|
|
});
|
|
} else if (aTest.fns) {
|
|
aTest.fns.forEach(fn => {
|
|
const niceWhat = `${aTest.objPath.replace('window.', '')}.${fn}`;
|
|
test(`${niceWhat}: an function override should have been applied`, async t => {
|
|
const { sandbox, server } = t.context;
|
|
const results = await sandbox.evaluate(testFn, aTest.objPath, fn);
|
|
if (results.tests) {
|
|
results.tests.forEach(({ test, msg }) => {
|
|
t.true(test, msg);
|
|
});
|
|
} else {
|
|
t.true(results.test, `${aTest.objPath}.${fn} was not updated`);
|
|
}
|
|
function testFn(objPath, fn) {
|
|
const existing = window.WombatTestUtil.getViaPath(
|
|
window.wombatSandbox,
|
|
objPath
|
|
);
|
|
const original = window.WombatTestUtil.getOriginalWinDomViaPath(
|
|
objPath
|
|
);
|
|
const result = {};
|
|
if (existing[fn] && original[fn]) {
|
|
result.test = existing[fn].toString() !== original[fn].toString();
|
|
} else if (existing[fn]) {
|
|
result.tests = [
|
|
{
|
|
test: existing[fn] !== null,
|
|
msg: `${objPath}.${fn} was not overridden (is undefined/null)`
|
|
},
|
|
{
|
|
test: !existing[fn].toString().includes('[native code]'),
|
|
msg: `${objPath}.${fn} was not overridden at all`
|
|
}
|
|
];
|
|
} else {
|
|
result.test = false;
|
|
}
|
|
return result;
|
|
}
|
|
});
|
|
});
|
|
} else if (aTest.persisted) {
|
|
aTest.persisted.forEach(fn => {
|
|
const niceWhat = `${aTest.objPath.replace('window.', '')}.${fn}`;
|
|
test(`${niceWhat}: the original function should exist on the overridden object`, async t => {
|
|
const { sandbox, server } = t.context;
|
|
t.true(
|
|
await sandbox.evaluate(testFn, aTest.objPath, fn),
|
|
`the original function '${niceWhat}' was not persisted`
|
|
);
|
|
function testFn(objPath, fn) {
|
|
const existing = window.WombatTestUtil.getViaPath(
|
|
window.wombatSandbox,
|
|
objPath
|
|
);
|
|
const original = window.WombatTestUtil.getOriginalWinDomViaPath(
|
|
objPath
|
|
);
|
|
return existing[fn].toString() === original[fn].toString();
|
|
}
|
|
});
|
|
});
|
|
}
|
|
});
|