fix(webkit): use protocol to serialize values instead of JSON (#373)
This commit is contained in:
parent
04bf728364
commit
9fb6a68b25
|
|
@ -141,7 +141,7 @@ export class WKExecutionContext implements js.ExecutionContextDelegate {
|
||||||
if (!returnByValue)
|
if (!returnByValue)
|
||||||
return context._createHandle(response.result);
|
return context._createHandle(response.result);
|
||||||
if (response.result.objectId)
|
if (response.result.objectId)
|
||||||
return this._returnObjectByValue(response.result.objectId);
|
return this._returnObjectByValue(response.result.objectId).catch(() => undefined);
|
||||||
return valueFromRemoteObject(response.result);
|
return valueFromRemoteObject(response.result);
|
||||||
}).catch(rewriteError);
|
}).catch(rewriteError);
|
||||||
|
|
||||||
|
|
@ -182,9 +182,6 @@ export class WKExecutionContext implements js.ExecutionContextDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
function rewriteError(error: Error): Protocol.Runtime.evaluateReturnValue {
|
function rewriteError(error: Error): Protocol.Runtime.evaluateReturnValue {
|
||||||
if (error.message.includes('Object couldn\'t be returned by value'))
|
|
||||||
return {result: {type: 'undefined'}};
|
|
||||||
|
|
||||||
if (error.message.includes('Missing injected script for given'))
|
if (error.message.includes('Missing injected script for given'))
|
||||||
throw new Error('Execution context was destroyed, most likely because of a navigation.');
|
throw new Error('Execution context was destroyed, most likely because of a navigation.');
|
||||||
throw error;
|
throw error;
|
||||||
|
|
@ -219,18 +216,9 @@ export class WKExecutionContext implements js.ExecutionContextDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
private _returnObjectByValue(objectId: Protocol.Runtime.RemoteObjectId) {
|
private _returnObjectByValue(objectId: Protocol.Runtime.RemoteObjectId) {
|
||||||
const serializeFunction = function() {
|
|
||||||
try {
|
|
||||||
return JSON.stringify(this);
|
|
||||||
} catch (e) {
|
|
||||||
if (e instanceof TypeError)
|
|
||||||
return void 0;
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return this._session.send('Runtime.callFunctionOn', {
|
return this._session.send('Runtime.callFunctionOn', {
|
||||||
// Serialize object using standard JSON implementation to correctly pass 'undefined'.
|
// Serialize object using standard JSON implementation to correctly pass 'undefined'.
|
||||||
functionDeclaration: serializeFunction + '\n' + suffix + '\n',
|
functionDeclaration: 'function(){return this}\n' + suffix + '\n',
|
||||||
objectId: objectId,
|
objectId: objectId,
|
||||||
returnByValue: true
|
returnByValue: true
|
||||||
}).catch(e => {
|
}).catch(e => {
|
||||||
|
|
@ -240,12 +228,7 @@ export class WKExecutionContext implements js.ExecutionContextDelegate {
|
||||||
}).then(serializeResponse => {
|
}).then(serializeResponse => {
|
||||||
if (serializeResponse.wasThrown)
|
if (serializeResponse.wasThrown)
|
||||||
throw new Error('Serialization failed: ' + serializeResponse.result.description);
|
throw new Error('Serialization failed: ' + serializeResponse.result.description);
|
||||||
// This is the case of too long property chain, not serializable to json string.
|
return serializeResponse.result.value;
|
||||||
if (serializeResponse.result.type === 'undefined')
|
|
||||||
return undefined;
|
|
||||||
if (serializeResponse.result.type !== 'string')
|
|
||||||
throw new Error('Unexpected result of JSON.stringify: ' + JSON.stringify(serializeResponse, null, 2));
|
|
||||||
return JSON.parse(serializeResponse.result.value);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ module.exports.describe = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
|
||||||
await page.goto(server.PREFIX + '/global-var.html');
|
await page.goto(server.PREFIX + '/global-var.html');
|
||||||
expect(await page.evaluate('globalVar')).toBe(123);
|
expect(await page.evaluate('globalVar')).toBe(123);
|
||||||
});
|
});
|
||||||
it.skip(FFOX || WEBKIT)('should return undefined for objects with symbols', async({page, server}) => {
|
it.skip(FFOX)('should return undefined for objects with symbols', async({page, server}) => {
|
||||||
expect(await page.evaluate(() => [Symbol('foo4')])).toBe(undefined);
|
expect(await page.evaluate(() => [Symbol('foo4')])).toBe(undefined);
|
||||||
});
|
});
|
||||||
it('should work with function shorthands', async({page, server}) => {
|
it('should work with function shorthands', async({page, server}) => {
|
||||||
|
|
@ -259,7 +259,7 @@ module.exports.describe = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
|
||||||
})).catch(e => error = e);
|
})).catch(e => error = e);
|
||||||
expect(error.message).toContain('Error in promise');
|
expect(error.message).toContain('Error in promise');
|
||||||
});
|
});
|
||||||
it.skip(WEBKIT)('should work even when JSON is set to null', async ({ page }) => {
|
it('should work even when JSON is set to null', async ({ page }) => {
|
||||||
await page.evaluate(() => { window.JSON.stringify = null; window.JSON = null; });
|
await page.evaluate(() => { window.JSON.stringify = null; window.JSON = null; });
|
||||||
const result = await page.evaluate(() => ({abc: 123}));
|
const result = await page.evaluate(() => ({abc: 123}));
|
||||||
expect(result).toEqual({abc: 123});
|
expect(result).toEqual({abc: 123});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue