feat(executioncontext): support bigints transferring (#4016)

Refs: https://chromedevtools.github.io/devtools-protocol/tot/Runtime#type-UnserializableValue
This commit is contained in:
Vse Mozhet Byt 2019-03-15 19:20:48 +02:00 committed by Andrey Lushnikov
parent 27cf8594c2
commit 854b1c0912
5 changed files with 20 additions and 4 deletions

View File

@ -1245,7 +1245,7 @@ List of all available devices is available in the source code: [DeviceDescriptor
If the function passed to the `page.evaluate` returns a [Promise], then `page.evaluate` would wait for the promise to resolve and return its value.
If the function passed to the `page.evaluate` returns a non-[Serializable] value, then `page.evaluate` resolves to `undefined`.
If the function passed to the `page.evaluate` returns a non-[Serializable] value, then `page.evaluate` resolves to `undefined`. DevTools Protocol also supports transferring some additional values that are not serializable by `JSON`: `-0`, `NaN`, `Infinity`, `-Infinity`, and bigint literals.
Passing arguments to `pageFunction`:
```js
@ -2031,7 +2031,7 @@ for (const worker of page.workers())
If the function passed to the `worker.evaluate` returns a [Promise], then `worker.evaluate` would wait for the promise to resolve and return its value.
If the function passed to the `worker.evaluate` returns a non-[Serializable] value, then `worker.evaluate` resolves to `undefined`.
If the function passed to the `worker.evaluate` returns a non-[Serializable] value, then `worker.evaluate` resolves to `undefined`. DevTools Protocol also supports transferring some additional values that are not serializable by `JSON`: `-0`, `NaN`, `Infinity`, `-Infinity`, and bigint literals.
Shortcut for [(await worker.executionContext()).evaluate(pageFunction, ...args)](#executioncontextevaluatepagefunction-args).
@ -2498,7 +2498,7 @@ Gets the full HTML contents of the frame, including the doctype.
If the function passed to the `frame.evaluate` returns a [Promise], then `frame.evaluate` would wait for the promise to resolve and return its value.
If the function passed to the `frame.evaluate` returns a non-[Serializable] value, then `frame.evaluate` resolves to `undefined`.
If the function passed to the `frame.evaluate` returns a non-[Serializable] value, then `frame.evaluate` resolves to `undefined`. DevTools Protocol also supports transferring some additional values that are not serializable by `JSON`: `-0`, `NaN`, `Infinity`, `-Infinity`, and bigint literals.
```js
const result = await frame.evaluate(() => {
@ -2817,6 +2817,8 @@ Besides pages, execution contexts can be found in [workers](https://developer.mo
If the function passed to the `executionContext.evaluate` returns a [Promise], then `executionContext.evaluate` would wait for the promise to resolve and return its value.
If the function passed to the `executionContext.evaluate` returns a non-[Serializable] value, then `executionContext.evaluate` resolves to `undefined`. DevTools Protocol also supports transferring some additional values that are not serializable by `JSON`: `-0`, `NaN`, `Infinity`, `-Infinity`, and bigint literals.
```js
const executionContext = await page.mainFrame().executionContext();
const result = await executionContext.evaluate(() => Promise.resolve(8 * 7));

View File

@ -127,6 +127,8 @@ class ExecutionContext {
* @this {ExecutionContext}
*/
function convertArgument(arg) {
if (typeof arg === 'bigint') // eslint-disable-line valid-typeof
return { unserializableValue: `${arg.toString()}n` };
if (Object.is(arg, -0))
return { unserializableValue: '-0' };
if (Object.is(arg, Infinity))

View File

@ -66,6 +66,8 @@ class Helper {
static valueFromRemoteObject(remoteObject) {
assert(!remoteObject.objectId, 'Cannot extract value when objectId is given');
if (remoteObject.unserializableValue) {
if (remoteObject.type === 'bigint' && typeof BigInt !== 'undefined')
return BigInt(remoteObject.unserializableValue.replace('n', ''));
switch (remoteObject.unserializableValue) {
case '-0':
return -0;

View File

@ -23,6 +23,8 @@ try {
asyncawait = false;
}
const bigint = typeof BigInt !== 'undefined';
module.exports.addTests = function({testRunner, expect}) {
const {describe, xdescribe, fdescribe} = testRunner;
const {it, fit, xit, it_fails_ffox} = testRunner;
@ -33,6 +35,10 @@ module.exports.addTests = function({testRunner, expect}) {
const result = await page.evaluate(() => 7 * 3);
expect(result).toBe(21);
});
(bigint ? it : xit)('should transfer BigInt', async({page, server}) => {
const result = await page.evaluate(a => a, BigInt(42));
expect(result).toBe(BigInt(42));
});
it('should transfer NaN', async({page, server}) => {
const result = await page.evaluate(a => a, NaN);
expect(Object.is(result, NaN)).toBe(true);
@ -135,6 +141,10 @@ module.exports.addTests = function({testRunner, expect}) {
expect(result).not.toBe(object);
expect(result).toEqual(object);
});
(bigint ? it : xit)('should return BigInt', async({page, server}) => {
const result = await page.evaluate(() => BigInt(42));
expect(result).toBe(BigInt(42));
});
it('should return NaN', async({page, server}) => {
const result = await page.evaluate(() => NaN);
expect(Object.is(result, NaN)).toBe(true);

View File

@ -3,7 +3,7 @@
"noEmit": true,
"allowJs": true,
"checkJs": true,
"target": "es2017"
"target": "ESNext"
},
"include": [
"lib"