fix(page.evaluate): jsonValue should ignore toJSON property (#1098)

Currently, JSHandle.jsonValue() is implemented as in-page JSON.stringify
call and consequent JSON.parse in node. This approach proved to be
unfortunate for automation purposes: if page author overrode the
Object.prototype.toJSON method, then it's harder for puppeteer to
interact with the page.

This patch switches JSHandle.jsonValue to use protocol serialization
that ignores toJSON property. THis also changes the `page.evaluate`
behavior since it is based on JSHandle.jsonValue().

Fixes #1003.

BREAKING CHANGE:
`page.evaluate` no longer calls toJSON when generating return value.
For the old behavior, do JSON.parse/JSON.stringify manually:

```js
const json = JSON.parse(await page.evaluate(() => JSON.stringify(obj)));
```
This commit is contained in:
Andrey Lushnikov
2017-10-20 10:45:49 -07:00
committed by GitHub
parent 0f64f3e984
commit 5c92ba222a
3 changed files with 13 additions and 6 deletions

View File

@@ -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);
}