diff --git a/docs/api.md b/docs/api.md index cefdf22853d..f733f7f23a0 100644 --- a/docs/api.md +++ b/docs/api.md @@ -1677,7 +1677,9 @@ Fetches a single property from the referenced object. #### jsHandle.jsonValue() - returns: <[Promise]<[Object]>> -Returns a JSON representation of the object. The JSON is generated by running [`JSON.stringify`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify) on the object in page and consequent [`JSON.parse`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse) in puppeteer. +Returns a JSON representation of the object. If the object has a +[`toJSON`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#toJSON()_behavior) +function, it **will not be called**. > **NOTE** The method will throw if the referenced object is not stringifiable. diff --git a/lib/ExecutionContext.js b/lib/ExecutionContext.js index 325cd801826..def4d7d0eeb 100644 --- a/lib/ExecutionContext.js +++ b/lib/ExecutionContext.js @@ -168,8 +168,13 @@ class JSHandle { */ async jsonValue() { if (this._remoteObject.objectId) { - const jsonString = await this._context.evaluate(object => JSON.stringify(object), this); - return JSON.parse(jsonString); + const response = await this._client.send('Runtime.callFunctionOn', { + functionDeclaration: 'function() { return this; }', + objectId: this._remoteObject.objectId, + returnByValue: true, + awaitPromise: true, + }); + return helper.valueFromRemoteObject(response.result); } return helper.valueFromRemoteObject(this._remoteObject); } diff --git a/test/test.js b/test/test.js index 32e03c0f059..26443dcda8a 100644 --- a/test/test.js +++ b/test/test.js @@ -429,16 +429,16 @@ describe('Page', function() { const json = await aHandle.jsonValue(); expect(json).toEqual({foo: 'bar'}); })); - it('should work with dates', SX(async function() { + it('should not work with dates', SX(async function() { const dateHandle = await page.evaluateHandle(() => new Date('2017-09-26T00:00:00.000Z')); const json = await dateHandle.jsonValue(); - expect(json).toBe('2017-09-26T00:00:00.000Z'); + expect(json).toEqual({}); })); it('should throw for circular objects', SX(async function() { const windowHandle = await page.evaluateHandle('window'); let error = null; await windowHandle.jsonValue().catch(e => error = e); - expect(error.message).toContain('Converting circular structure to JSON'); + expect(error.message).toContain('Object reference chain is too long'); })); });