diff --git a/lib/FrameManager.js b/lib/FrameManager.js index 5e0416b6..c7d649b5 100644 --- a/lib/FrameManager.js +++ b/lib/FrameManager.js @@ -169,12 +169,33 @@ class FrameManager extends EventEmitter { } let syncExpression = helper.evaluationString(fun, ...args); 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) { let message = await helper.getExceptionMessage(this._client, exceptionDetails); throw new Error('Evaluation failed: ' + message); } - return remoteObject.value; + 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; + let response = await this._client.send('Runtime.callFunctionOn', { + objectId: remoteObject.objectId, + functionDeclaration: 'function() { return this; }', + returnByValue: true, + }); + return response.result.value; } } diff --git a/test/test.js b/test/test.js index a1497653..4f691cfd 100644 --- a/test/test.js +++ b/test/test.js @@ -80,6 +80,28 @@ describe('Puppeteer', function() { expect(error).toBeTruthy(); 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() {