Add support for unserializable values in Page.evaluate

This patch adds support for unserializable return values in
Page.evaluate.

Currently, these values are:
- NaN
- Infinity
- -Infinity
- -0

Fixes #51.
This commit is contained in:
Andrey Lushnikov 2017-07-06 10:41:01 -07:00
parent 62111fbc08
commit 773a09a8cf
2 changed files with 45 additions and 2 deletions

View File

@ -169,12 +169,33 @@ class FrameManager extends EventEmitter {
} }
let syncExpression = helper.evaluationString(fun, ...args); let syncExpression = helper.evaluationString(fun, ...args);
let expression = `Promise.resolve(${syncExpression})`; let expression = `Promise.resolve(${syncExpression})`;
let { exceptionDetails, result: remoteObject } = await this._client.send('Runtime.evaluate', { expression, contextId, returnByValue: true, awaitPromise: true }); let { exceptionDetails, result: remoteObject } = await this._client.send('Runtime.evaluate', { expression, contextId, returnByValue: false, awaitPromise: true });
if (exceptionDetails) { if (exceptionDetails) {
let message = await helper.getExceptionMessage(this._client, exceptionDetails); let message = await helper.getExceptionMessage(this._client, exceptionDetails);
throw new Error('Evaluation failed: ' + message); throw new Error('Evaluation failed: ' + message);
} }
if (remoteObject.unserializableValue) {
switch (remoteObject.unserializableValue) {
case '-0':
return -0;
case 'NaN':
return NaN;
case 'Infinity':
return Infinity;
case '-Infinity':
return -Infinity;
default:
throw new Error('Unsupported unserializable value: ' + remoteObject.unserializableValue);
}
}
if (!remoteObject.objectId)
return remoteObject.value; return remoteObject.value;
let response = await this._client.send('Runtime.callFunctionOn', {
objectId: remoteObject.objectId,
functionDeclaration: 'function() { return this; }',
returnByValue: true,
});
return response.result.value;
} }
} }

View File

@ -80,6 +80,28 @@ describe('Puppeteer', function() {
expect(error).toBeTruthy(); expect(error).toBeTruthy();
expect(error.message).toContain('not is not defined'); expect(error.message).toContain('not is not defined');
})); }));
it('should return complex objects', SX(async function() {
const object = {foo: 'bar!'};
let result = await page.evaluate(a => a, object);
expect(result).not.toBe(object);
expect(result).toEqual(object);
}));
it('should return NaN', SX(async function() {
let result = await page.evaluate(() => NaN);
expect(Object.is(result, NaN)).toBe(true);
}));
it('should return -0', SX(async function() {
let result = await page.evaluate(() => -0);
expect(Object.is(result, -0)).toBe(true);
}));
it('should return Infinity', SX(async function() {
let result = await page.evaluate(() => Infinity);
expect(Object.is(result, Infinity)).toBe(true);
}));
it('should return -Infinity', SX(async function() {
let result = await page.evaluate(() => -Infinity);
expect(Object.is(result, -Infinity)).toBe(true);
}));
}); });
describe('Frame.evaluate', function() { describe('Frame.evaluate', function() {