Upload Kmake

This commit is contained in:
Gorochu
2026-05-26 23:36:42 -07:00
parent ba051b2f74
commit 555ec72358
41615 changed files with 13344630 additions and 1 deletions

View File

@ -0,0 +1,250 @@
Test for Runtime.addBinding.
Running test: testBasic
Add binding inside session1..
Call binding..
binding called in session1
{
method : Runtime.bindingCalled
params : {
executionContextId : <executionContextId>
name : send
payload : payload
}
}
Add binding inside session2..
Call binding..
binding called in session1
{
method : Runtime.bindingCalled
params : {
executionContextId : <executionContextId>
name : send
payload : payload
}
}
binding called in session2
{
method : Runtime.bindingCalled
params : {
executionContextId : <executionContextId>
name : send
payload : payload
}
}
Disable agent inside session1..
Call binding..
binding called in session1
{
method : Runtime.bindingCalled
params : {
executionContextId : <executionContextId>
name : send
payload : payload
}
}
binding called in session2
{
method : Runtime.bindingCalled
params : {
executionContextId : <executionContextId>
name : send
payload : payload
}
}
Disable agent inside session2..
Call binding..
binding called in session1
{
method : Runtime.bindingCalled
params : {
executionContextId : <executionContextId>
name : send
payload : payload
}
}
binding called in session2
{
method : Runtime.bindingCalled
params : {
executionContextId : <executionContextId>
name : send
payload : payload
}
}
Enable agent inside session1..
Call binding..
binding called in session1
{
method : Runtime.bindingCalled
params : {
executionContextId : <executionContextId>
name : send
payload : payload
}
}
binding called in session2
{
method : Runtime.bindingCalled
params : {
executionContextId : <executionContextId>
name : send
payload : payload
}
}
Running test: testReconnect
Add binding inside session..
Reconnect..
binding called in session1
{
method : Runtime.bindingCalled
params : {
executionContextId : <executionContextId>
name : send
payload : payload
}
}
Running test: testBindingOverrides
Add send function on global object..
Add binding inside session..
Call binding..
binding called in session1
{
method : Runtime.bindingCalled
params : {
executionContextId : <executionContextId>
name : send
payload : payload
}
}
Running test: testRemoveBinding
Add binding inside session..
Call binding..
binding called in session1
{
method : Runtime.bindingCalled
params : {
executionContextId : <executionContextId>
name : send
payload : payload
}
}
Remove binding inside session..
Call binding..
Running test: testAddBindingToContextById
Call binding in default context (binding should NOT be exposed)
Call binding in target context (binding should be exposed)
binding called in session1
{
method : Runtime.bindingCalled
params : {
executionContextId : <executionContextId>
name : frobnicate
payload : message
}
}
Call binding in newly created context (binding should NOT be exposed)
Running test: testAddBindingToMultipleContextsById
Call binding in default context (binding should be exposed)
binding called in session1
{
method : Runtime.bindingCalled
params : {
executionContextId : <executionContextId>
name : frobnicate
payload : message
}
}
Call binding in target context (binding should be exposed)
binding called in session1
{
method : Runtime.bindingCalled
params : {
executionContextId : <executionContextId>
name : frobnicate
payload : message
}
}
Running test: testAddBindingToMultipleContextsInDifferentContextGroups
Call binding in default context (binding should be exposed)
binding called in group1/session1
{
method : Runtime.bindingCalled
params : {
executionContextId : <executionContextId>
name : frobnicate
payload : message
}
}
Call binding in target context (binding should be exposed)
binding called in group2/session1
{
method : Runtime.bindingCalled
params : {
executionContextId : <executionContextId>
name : frobnicate
payload : message
}
}
Running test: testAddBindingToContextByName
Call binding in default context (binding should NOT be exposed)
Call binding in Foo (binding should be exposed)
binding called in session1
{
method : Runtime.bindingCalled
params : {
executionContextId : <executionContextId>
name : frobnicate
payload : message
}
}
Call binding in Bar (binding should NOT be exposed)
Call binding in newly-created Foo (binding should be exposed)
binding called in session1
{
method : Runtime.bindingCalled
params : {
executionContextId : <executionContextId>
name : frobnicate
payload : message
}
}
Call binding in newly-created Bazz (binding should NOT be exposed)
Running test: testErrors
{
error : {
code : -32602
message : Invalid executionContextName
}
id : <messageId>
}
{
error : {
code : -32602
message : executionContextName is mutually exclusive with executionContextId
}
id : <messageId>
}
{
error : {
code : -32602
message : Cannot find execution context with given executionContextId
}
id : <messageId>
}

View File

@ -0,0 +1,188 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
InspectorTest.log('Test for Runtime.addBinding.');
InspectorTest.runAsyncTestSuite([
async function testBasic() {
const {contextGroup, sessions: [session1, session2]} = setupSessions(2);
InspectorTest.log('\nAdd binding inside session1..');
session1.Protocol.Runtime.addBinding({name: 'send'});
InspectorTest.log('Call binding..');
await session1.Protocol.Runtime.evaluate({expression: `send('payload')`});
InspectorTest.log('\nAdd binding inside session2..');
session2.Protocol.Runtime.addBinding({name: 'send'});
InspectorTest.log('Call binding..');
await session2.Protocol.Runtime.evaluate({expression: `send('payload')`});
InspectorTest.log('\nDisable agent inside session1..');
session1.Protocol.Runtime.disable();
InspectorTest.log('Call binding..');
await session2.Protocol.Runtime.evaluate({expression: `send('payload')`});
InspectorTest.log('\nDisable agent inside session2..');
session2.Protocol.Runtime.disable();
InspectorTest.log('Call binding..');
await session2.Protocol.Runtime.evaluate({expression: `send('payload')`});
InspectorTest.log('\nEnable agent inside session1..');
session1.Protocol.Runtime.enable();
InspectorTest.log('Call binding..');
await session2.Protocol.Runtime.evaluate({expression: `send('payload')`});
},
async function testReconnect() {
const {contextGroup, sessions: [session]} = setupSessions(1);
InspectorTest.log('\nAdd binding inside session..');
await session.Protocol.Runtime.addBinding({name: 'send'});
InspectorTest.log('Reconnect..');
session.reconnect();
await session.Protocol.Runtime.evaluate({expression: `send('payload')`});
},
async function testBindingOverrides() {
const {contextGroup, sessions: [session]} = setupSessions(1);
InspectorTest.log('\nAdd send function on global object..');
session.Protocol.Runtime.evaluate({expression: 'send = () => 42'});
InspectorTest.log('Add binding inside session..');
session.Protocol.Runtime.addBinding({name: 'send'});
InspectorTest.log('Call binding..');
await session.Protocol.Runtime.evaluate({expression: `send('payload')`});
},
async function testRemoveBinding() {
const {contextGroup, sessions: [session]} = setupSessions(1);
InspectorTest.log('\nAdd binding inside session..');
session.Protocol.Runtime.addBinding({name: 'send'});
InspectorTest.log('Call binding..');
await session.Protocol.Runtime.evaluate({expression: `send('payload')`});
InspectorTest.log('Remove binding inside session..');
session.Protocol.Runtime.removeBinding({name: 'send'});
InspectorTest.log('Call binding..');
await session.Protocol.Runtime.evaluate({expression: `send('payload')`});
},
async function testAddBindingToContextById() {
const {contextGroup, sessions: [session]} = setupSessions(1);
const contextId1 = (await session.Protocol.Runtime.onceExecutionContextCreated()).params.context.id;
contextGroup.createContext();
const contextId2 = (await session.Protocol.Runtime.onceExecutionContextCreated()).params.context.id;
await session.Protocol.Runtime.addBinding({name: 'frobnicate', executionContextId: contextId2});
const expression = `frobnicate('message')`;
InspectorTest.log('Call binding in default context (binding should NOT be exposed)');
await session.Protocol.Runtime.evaluate({expression});
InspectorTest.log('Call binding in target context (binding should be exposed)');
await session.Protocol.Runtime.evaluate({expression, contextId: contextId2});
InspectorTest.log('Call binding in newly created context (binding should NOT be exposed)');
contextGroup.createContext();
const contextId3 = (await session.Protocol.Runtime.onceExecutionContextCreated()).params.context.id;
await session.Protocol.Runtime.evaluate({expression, contextId: contextId3});
},
async function testAddBindingToMultipleContextsById() {
const {contextGroup, sessions: [session]} = setupSessions(1);
const contextId1 = (await session.Protocol.Runtime.onceExecutionContextCreated()).params.context.id;
contextGroup.createContext();
const contextId2 = (await session.Protocol.Runtime.onceExecutionContextCreated()).params.context.id;
await session.Protocol.Runtime.addBinding({name: 'frobnicate', executionContextId: contextId1});
await session.Protocol.Runtime.addBinding({name: 'frobnicate', executionContextId: contextId2});
const expression = `frobnicate('message')`;
InspectorTest.log('Call binding in default context (binding should be exposed)');
await session.Protocol.Runtime.evaluate({expression});
InspectorTest.log('Call binding in target context (binding should be exposed)');
await session.Protocol.Runtime.evaluate({expression, contextId: contextId2});
},
async function testAddBindingToMultipleContextsInDifferentContextGroups() {
const sessions1 = setupSessions(1, 'group1/');
const session1 = sessions1.sessions[0];
const contextId1 = (await session1.Protocol.Runtime.onceExecutionContextCreated()).params.context.id;
const sessions2 = setupSessions(1, 'group2/');
const session2 = sessions2.sessions[0];
const contextId2 = (await session2.Protocol.Runtime.onceExecutionContextCreated()).params.context.id;
await session1.Protocol.Runtime.addBinding({name: 'frobnicate', executionContextId: contextId1});
await session2.Protocol.Runtime.addBinding({name: 'frobnicate', executionContextId: contextId2});
const expression = `frobnicate('message')`;
InspectorTest.log('Call binding in default context (binding should be exposed)');
await session1.Protocol.Runtime.evaluate({expression, contextId: contextId1});
InspectorTest.log('Call binding in target context (binding should be exposed)');
await session2.Protocol.Runtime.evaluate({expression, contextId: contextId2});
},
async function testAddBindingToContextByName() {
const {contextGroup, sessions: [session]} = setupSessions(1);
const defaultContext = (await session.Protocol.Runtime.onceExecutionContextCreated()).params.context.id;
contextGroup.createContext("foo");
const contextFoo = (await session.Protocol.Runtime.onceExecutionContextCreated()).params.context.id;
contextGroup.createContext("bar");
const contextBar = (await session.Protocol.Runtime.onceExecutionContextCreated()).params.context.id;
await session.Protocol.Runtime.addBinding({name: 'frobnicate', executionContextName: 'foo'});
const expression = `frobnicate('message')`;
InspectorTest.log('Call binding in default context (binding should NOT be exposed)');
await session.Protocol.Runtime.evaluate({expression});
InspectorTest.log('Call binding in Foo (binding should be exposed)');
await session.Protocol.Runtime.evaluate({expression, contextId: contextFoo});
InspectorTest.log('Call binding in Bar (binding should NOT be exposed)');
await session.Protocol.Runtime.evaluate({expression, contextId: contextBar});
contextGroup.createContext("foo");
const contextFoo2 = (await session.Protocol.Runtime.onceExecutionContextCreated()).params.context.id;
InspectorTest.log('Call binding in newly-created Foo (binding should be exposed)');
await session.Protocol.Runtime.evaluate({expression, contextId: contextFoo2});
contextGroup.createContext("bazz");
const contextBazz = (await session.Protocol.Runtime.onceExecutionContextCreated()).params.context.id;
InspectorTest.log('Call binding in newly-created Bazz (binding should NOT be exposed)');
await session.Protocol.Runtime.evaluate({expression, contextId: contextBazz});
},
async function testErrors() {
const {contextGroup, sessions: [session]} = setupSessions(1);
let err = await session.Protocol.Runtime.addBinding({name: 'frobnicate', executionContextName: ''});
InspectorTest.logMessage(err);
err = await session.Protocol.Runtime.addBinding({name: 'frobnicate', executionContextName: 'foo', executionContextId: 1});
InspectorTest.logMessage(err);
err = await session.Protocol.Runtime.addBinding({name: 'frobnicate', executionContextId: 2128506});
InspectorTest.logMessage(err);
}
]);
function setupSessions(num, prefix = '') {
const contextGroup = new InspectorTest.ContextGroup();
const sessions = [];
for (let i = 0; i < num; ++i) {
const session = contextGroup.connect();
sessions.push(session);
session.Protocol.Runtime.enable();
session.Protocol.Runtime.onBindingCalled(msg => {
InspectorTest.log(`binding called in ${prefix}session${i + 1}`);
InspectorTest.logMessage(msg);
});
}
return {contextGroup, sessions};
}

View File

@ -0,0 +1,122 @@
Tests that Runtime.awaitPromise works.
Running test: testResolvedPromise
{
id : <messageId>
result : {
result : {
description : 239
type : number
value : 239
}
}
}
Running test: testRejectedPromise
{
id : <messageId>
result : {
exceptionDetails : {
columnNumber : 0
exception : {
className : Object
description : Object
objectId : <objectId>
preview : {
description : Object
overflow : false
properties : [
[0] : {
name : a
type : number
value : 1
}
]
type : object
}
type : object
}
exceptionId : <exceptionId>
lineNumber : 0
text : Uncaught (in promise)
}
result : {
type : object
value : {
a : 1
}
}
}
}
Running test: testRejectedPromiseWithStack
{
id : <messageId>
result : {
exceptionDetails : {
columnNumber : 0
exception : {
description : 239
type : number
value : 239
}
exceptionId : <exceptionId>
lineNumber : 0
text : Uncaught (in promise)
}
result : {
description : 239
type : number
value : 239
}
}
}
Running test: testRejectedPromiseWithError
{
id : <messageId>
result : {
exceptionDetails : {
columnNumber : 0
exception : {
className : Error
description : Error: MyError at rejectPromiseWithAnError (test.js:25:20) at <anonymous>:1:1
objectId : <objectId>
subtype : error
type : object
}
exceptionId : <exceptionId>
lineNumber : 0
text : Uncaught (in promise) Error: MyError
}
result : {
className : Error
description : Error: MyError at rejectPromiseWithAnError (test.js:25:20) at <anonymous>:1:1
objectId : <objectId>
subtype : error
type : object
}
}
}
Running test: testPendingPromise
{
id : <messageId>
result : {
result : {
description : 239
type : number
value : 239
}
}
}
Running test: testResolvedWithoutArgsPromise
{
id : <messageId>
result : {
result : {
type : undefined
}
}
}

View File

@ -0,0 +1,122 @@
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --expose-gc
let {session, contextGroup, Protocol} = InspectorTest.start("Tests that Runtime.awaitPromise works.");
contextGroup.addScript(
`
var resolveCallback;
var rejectCallback;
function createPromise()
{
return new Promise((resolve, reject) => { resolveCallback = resolve; rejectCallback = reject });
}
function resolvePromise()
{
resolveCallback(239);
resolveCallback = undefined;
rejectCallback = undefined;
}
function rejectPromise()
{
rejectCallback(239);
resolveCallback = undefined;
rejectCallback = undefined;
}
function rejectPromiseWithAnError()
{
rejectCallback(new Error('MyError'));
resolveCallback = undefined;
rejectCallback = undefined;
}
function throwError()
{
throw new Error('MyError');
}
//# sourceURL=test.js`);
Protocol.Debugger.enable()
.then(() => Protocol.Debugger.setAsyncCallStackDepth({ maxDepth: 128 }))
.then(() => testSuite());
function testSuite()
{
InspectorTest.runTestSuite([
function testResolvedPromise(next)
{
Protocol.Runtime.evaluate({ expression: "Promise.resolve(239)"})
.then(result => Protocol.Runtime.awaitPromise({ promiseObjectId: result.result.result.objectId, returnByValue: false, generatePreview: true }))
.then(result => InspectorTest.logMessage(result))
.then(() => next());
},
function testRejectedPromise(next)
{
Protocol.Runtime.evaluate({ expression: "Promise.reject({ a : 1 })"})
.then(result => Protocol.Runtime.awaitPromise({ promiseObjectId: result.result.result.objectId, returnByValue: true, generatePreview: false }))
.then(result => InspectorTest.logMessage(result))
.then(() => next());
},
function testRejectedPromiseWithStack(next)
{
Protocol.Runtime.evaluate({ expression: "createPromise()"})
.then(result => scheduleRejectAndAwaitPromise(result))
.then(result => InspectorTest.logMessage(result))
.then(() => next());
function scheduleRejectAndAwaitPromise(result)
{
var promise = Protocol.Runtime.awaitPromise({ promiseObjectId: result.result.result.objectId });
Protocol.Runtime.evaluate({ expression: "rejectPromise()" });
return promise;
}
},
function testRejectedPromiseWithError(next)
{
Protocol.Runtime.evaluate({ expression: "createPromise()"})
.then(result => scheduleRejectAndAwaitPromise(result))
.then(result => InspectorTest.logMessage(result))
.then(() => next());
function scheduleRejectAndAwaitPromise(result)
{
var promise = Protocol.Runtime.awaitPromise({ promiseObjectId: result.result.result.objectId });
Protocol.Runtime.evaluate({ expression: "rejectPromiseWithAnError()" });
return promise;
}
},
function testPendingPromise(next)
{
Protocol.Runtime.evaluate({ expression: "createPromise()"})
.then(result => scheduleFulfillAndAwaitPromise(result))
.then(result => InspectorTest.logMessage(result))
.then(() => next());
function scheduleFulfillAndAwaitPromise(result)
{
var promise = Protocol.Runtime.awaitPromise({ promiseObjectId: result.result.result.objectId });
Protocol.Runtime.evaluate({ expression: "resolvePromise()" });
return promise;
}
},
function testResolvedWithoutArgsPromise(next)
{
Protocol.Runtime.evaluate({ expression: "Promise.resolve()"})
.then(result => Protocol.Runtime.awaitPromise({ promiseObjectId: result.result.result.objectId, returnByValue: true, generatePreview: false }))
.then(result => InspectorTest.logMessage(result))
.then(() => next());
}
]);
}

View File

@ -0,0 +1,329 @@
Tests that Runtime.callFunctionOn works with awaitPromise flag.
Running test: prepareTestSuite
Running test: testArguments
{
id : <messageId>
result : {
result : {
type : string
value : undefined|NaN|[object Object]|[object Object]
}
}
}
Running test: testUnserializableArguments
{
id : <messageId>
result : {
result : {
type : string
value : true|true|true|true|bigint
}
}
}
Running test: testComplexArguments
{
id : <messageId>
result : {
result : {
type : string
value : bar
}
}
}
Running test: testSyntaxErrorInFunction
{
id : <messageId>
result : {
exceptionDetails : {
columnNumber : 2
exception : {
className : SyntaxError
description : SyntaxError: Unexpected token '}'
objectId : <objectId>
subtype : error
type : object
}
exceptionId : <exceptionId>
lineNumber : 1
scriptId : <scriptId>
text : Uncaught
}
result : {
className : SyntaxError
description : SyntaxError: Unexpected token '}'
objectId : <objectId>
subtype : error
type : object
}
}
}
Running test: testExceptionInFunctionExpression
{
id : <messageId>
result : {
exceptionDetails : {
columnNumber : 15
exception : {
className : Error
description : Error at <anonymous>:1:22 at <anonymous>:1:36
objectId : <objectId>
subtype : error
type : object
}
exceptionId : <exceptionId>
lineNumber : 0
scriptId : <scriptId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 21
functionName :
lineNumber : 0
scriptId : <scriptId>
url :
}
[1] : {
columnNumber : 35
functionName :
lineNumber : 0
scriptId : <scriptId>
url :
}
]
}
text : Uncaught
}
result : {
className : Error
description : Error at <anonymous>:1:22 at <anonymous>:1:36
objectId : <objectId>
subtype : error
type : object
}
}
}
Running test: testFunctionReturnNotPromise
{
id : <messageId>
result : {
result : {
description : 239
type : number
value : 239
}
}
}
Running test: testFunctionReturnResolvedPromiseReturnByValue
{
id : <messageId>
result : {
result : {
type : object
value : {
a : 3
}
}
}
}
Running test: testFunctionReturnResolvedPromiseWithPreview
{
id : <messageId>
result : {
result : {
className : Object
description : Object
objectId : <objectId>
preview : {
description : Object
overflow : false
properties : [
[0] : {
name : a
type : number
value : 3
}
]
type : object
}
type : object
}
}
}
Running test: testFunctionReturnRejectedPromise
{
id : <messageId>
result : {
exceptionDetails : {
columnNumber : 0
exception : {
className : Object
description : Object
objectId : <objectId>
preview : {
description : Object
overflow : false
properties : [
[0] : {
name : a
type : number
value : 3
}
]
type : object
}
type : object
}
exceptionId : <exceptionId>
lineNumber : 0
text : Uncaught (in promise)
}
result : {
type : object
value : {
a : 3
}
}
}
}
Running test: testEvaluateOnExecutionContext
{
id : <messageId>
result : {
result : {
description : 70
type : number
value : 70
}
}
}
Running test: testEvaluateOnUniqueExecutionContext
{
id : <messageId>
result : {
result : {
description : 70
type : number
value : 70
}
}
}
Running test: testPassingBothObjectIdAndExecutionContextId
{
error : {
code : -32602
message : ObjectId, executionContextId and uniqueContextId must mutually exclude each other
}
id : <messageId>
}
Running test: testPassingBothObjectIdAndExecutionContextUniqueId
{
error : {
code : -32602
message : ObjectId, executionContextId and uniqueContextId must mutually exclude each other
}
id : <messageId>
}
Running test: testPassingTwoExecutionContextIds
{
error : {
code : -32602
message : ObjectId, executionContextId and uniqueContextId must mutually exclude each other
}
id : <messageId>
}
Running test: testPassingNeitherContextIdNorObjectId
{
error : {
code : -32602
message : Either objectId or executionContextId or uniqueContextId must be specified
}
id : <messageId>
}
Running test: testThrowNumber
{
id : <messageId>
result : {
exceptionDetails : {
columnNumber : 10
exception : {
description : 100500
type : number
value : 100500
}
exceptionId : <exceptionId>
lineNumber : 0
scriptId : <scriptId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 10
functionName :
lineNumber : 0
scriptId : <scriptId>
url :
}
]
}
text : Uncaught
}
result : {
description : 100500
type : number
value : 100500
}
}
}
Running test: testAsyncFunctionWithUnknownReferenceReturnByValue
{
id : <messageId>
result : {
exceptionDetails : {
columnNumber : 30
exception : {
className : ReferenceError
description : ReferenceError: does_not_exist is not defined at <anonymous>:1:30
objectId : <objectId>
subtype : error
type : object
}
exceptionId : <exceptionId>
lineNumber : 1
scriptId : <scriptId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 29
functionName :
lineNumber : 0
scriptId : <scriptId>
url :
}
]
}
text : Uncaught (in promise) ReferenceError: does_not_exist is not defined
}
result : {
type : object
value : {
}
}
}
}

View File

@ -0,0 +1,224 @@
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
let {session, contextGroup, Protocol} = InspectorTest.start('Tests that Runtime.callFunctionOn works with awaitPromise flag.');
let callFunctionOn = Protocol.Runtime.callFunctionOn.bind(Protocol.Runtime);
let remoteObject1;
let remoteObject2;
let executionContextId;
let executionContextUniqueId;
Protocol.Runtime.enable();
Protocol.Runtime.onExecutionContextCreated(messageObject => {
executionContextId = messageObject.params.context.id;
executionContextUniqueId = messageObject.params.context.uniqueId;
InspectorTest.runAsyncTestSuite(testSuite);
});
let testSuite = [
async function prepareTestSuite() {
let result = await Protocol.Runtime.evaluate({ expression: '({a : 1})' });
remoteObject1 = result.result.result;
result = await Protocol.Runtime.evaluate({ expression: '({a : 2})' });
remoteObject2 = result.result.result;
await Protocol.Runtime.evaluate({ expression: 'globalObjectProperty = 42;' });
},
async function testArguments() {
InspectorTest.logMessage(await callFunctionOn({
objectId: remoteObject1.objectId,
functionDeclaration: 'function(arg1, arg2, arg3, arg4) { return \'\' + arg1 + \'|\' + arg2 + \'|\' + arg3 + \'|\' + arg4; }',
arguments: prepareArguments([undefined, NaN, remoteObject2, remoteObject1]),
returnByValue: true,
generatePreview: false,
awaitPromise: false
}));
},
async function testUnserializableArguments() {
InspectorTest.logMessage(await callFunctionOn({
objectId: remoteObject1.objectId,
functionDeclaration: 'function(arg1, arg2, arg3, arg4, arg5) { return \'\' + Object.is(arg1, -0) + \'|\' + Object.is(arg2, NaN) + \'|\' + Object.is(arg3, Infinity) + \'|\' + Object.is(arg4, -Infinity) + \'|\' + (typeof arg5); }',
arguments: prepareArguments([-0, NaN, Infinity, -Infinity, 2n]),
returnByValue: true,
generatePreview: false,
awaitPromise: false
}));
},
async function testComplexArguments() {
InspectorTest.logMessage(await callFunctionOn({
objectId: remoteObject1.objectId,
functionDeclaration: 'function(arg) { return arg.foo; }',
arguments: prepareArguments([{foo: 'bar'}]),
returnByValue: true,
generatePreview: false,
awaitPromise: false
}));
},
async function testSyntaxErrorInFunction() {
InspectorTest.logMessage(await callFunctionOn({
objectId: remoteObject1.objectId,
functionDeclaration: '\n }',
arguments: prepareArguments([]),
returnByValue: false,
generatePreview: false,
awaitPromise: true
}));
},
async function testExceptionInFunctionExpression() {
InspectorTest.logMessage(await callFunctionOn({
objectId: remoteObject1.objectId,
functionDeclaration: '(function() { throw new Error() })()',
arguments: prepareArguments([]),
returnByValue: false,
generatePreview: false,
awaitPromise: true
}));
},
async function testFunctionReturnNotPromise() {
InspectorTest.logMessage(await callFunctionOn({
objectId: remoteObject1.objectId,
functionDeclaration: '(function() { return 239; })',
arguments: prepareArguments([]),
returnByValue: true,
generatePreview: false,
awaitPromise: true
}));
},
async function testFunctionReturnResolvedPromiseReturnByValue() {
InspectorTest.logMessage(await callFunctionOn({
objectId: remoteObject1.objectId,
functionDeclaration: '(function(arg) { return Promise.resolve({a : this.a + arg.a}); })',
arguments: prepareArguments([ remoteObject2 ]),
returnByValue: true,
generatePreview: false,
awaitPromise: true
}));
},
async function testFunctionReturnResolvedPromiseWithPreview() {
InspectorTest.logMessage(await callFunctionOn({
objectId: remoteObject1.objectId,
functionDeclaration: '(function(arg) { return Promise.resolve({a : this.a + arg.a}); })',
arguments: prepareArguments([ remoteObject2 ]),
returnByValue: false,
generatePreview: true,
awaitPromise: true
}));
},
async function testFunctionReturnRejectedPromise() {
InspectorTest.logMessage(await callFunctionOn({
objectId: remoteObject1.objectId,
functionDeclaration: '(function(arg) { return Promise.reject({a : this.a + arg.a}); })',
arguments: prepareArguments([ remoteObject2 ]),
returnByValue: true,
generatePreview: false,
awaitPromise: true
}));
},
async function testEvaluateOnExecutionContext() {
InspectorTest.logMessage(await callFunctionOn({
executionContextId,
functionDeclaration: '(function(arg) { return this.globalObjectProperty + arg; })',
arguments: prepareArguments([ 28 ]),
returnByValue: true,
generatePreview: false,
awaitPromise: false
}));
},
async function testEvaluateOnUniqueExecutionContext() {
InspectorTest.logMessage(await callFunctionOn({
uniqueContextId: executionContextUniqueId,
functionDeclaration: '(function(arg) { return this.globalObjectProperty + arg; })',
arguments: prepareArguments([ 28 ]),
returnByValue: true,
generatePreview: false,
awaitPromise: false
}));
},
async function testPassingBothObjectIdAndExecutionContextId() {
InspectorTest.logMessage(await callFunctionOn({
executionContextId,
objectId: remoteObject1.objectId,
functionDeclaration: '(function() { return 42; })',
arguments: prepareArguments([]),
returnByValue: true
}));
},
async function testPassingBothObjectIdAndExecutionContextUniqueId() {
InspectorTest.logMessage(await callFunctionOn({
uniqueContextId: executionContextUniqueId,
objectId: remoteObject1.objectId,
functionDeclaration: '(function() { return 42; })',
arguments: prepareArguments([]),
returnByValue: true
}));
},
async function testPassingTwoExecutionContextIds() {
InspectorTest.logMessage(await callFunctionOn({
executionContextId,
uniqueContextId: executionContextUniqueId,
functionDeclaration: '(function() { return 42; })',
arguments: prepareArguments([]),
returnByValue: true
}));
},
async function testPassingNeitherContextIdNorObjectId() {
InspectorTest.logMessage(await callFunctionOn({
functionDeclaration: '(function() { return 42; })',
arguments: prepareArguments([]),
returnByValue: true
}));
},
async function testThrowNumber() {
InspectorTest.logMessage(await callFunctionOn({
executionContextId,
functionDeclaration: '(() => { throw 100500; } )',
arguments: prepareArguments([]),
returnByValue: true,
generatePreview: false,
awaitPromise: true
}));
},
async function testAsyncFunctionWithUnknownReferenceReturnByValue() {
InspectorTest.logMessage(await callFunctionOn({
executionContextId,
functionDeclaration: '(async () => does_not_exist.click())',
arguments: prepareArguments([]),
returnByValue: true,
generatePreview: false,
awaitPromise: true
}));
},
];
function prepareArguments(args) {
return args.map(arg => {
if (Object.is(arg, -0))
return {unserializableValue: '-0'};
if (Object.is(arg, NaN) || Object.is(arg, Infinity) || Object.is(arg, -Infinity))
return {unserializableValue: arg + ''};
if (typeof arg === 'bigint')
return {unserializableValue: arg + 'n'};
if (arg && arg.objectId)
return {objectId: arg.objectId};
return {value: arg};
});
}

View File

@ -0,0 +1,9 @@
Tests side-effect-free Runtime.callFunctionOn()
Running test: testCallFunctionOnSideEffectFree
function getA() { return this.a; }: ok
function setA(a) { this.a = a; }: throws
function getB() { return this.b; }: ok
function setB(b) { this.b = b; }: throws
function setSomeGlobal() { globalThis.someGlobal = this; }: throws
function localSideEffect() { const date = new Date(); date.setDate(this.a); return date; }: ok

View File

@ -0,0 +1,31 @@
// Copyright 2021 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
let {session, contextGroup, Protocol} =
InspectorTest.start('Tests side-effect-free Runtime.callFunctionOn()');
async function check(callable, object, ...args) {
const functionDeclaration = callable.toString();
const {result:{exceptionDetails}} = await Protocol.Runtime.callFunctionOn({
objectId: object.objectId,
functionDeclaration,
arguments: args.map(arg => (arg && arg.objectId) ? {objectId: arg.objectId} : {value: arg}),
throwOnSideEffect: true,
});
InspectorTest.log(`${functionDeclaration}: ${exceptionDetails ? 'throws' : 'ok'}`);
};
InspectorTest.runAsyncTestSuite([
async function testCallFunctionOnSideEffectFree() {
await Protocol.Runtime.enable();
const {result: {result: object}} = await Protocol.Runtime.evaluate({ expression: '({a: 1, b: ""})'});
await check(function getA() { return this.a; }, object);
await check(function setA(a) { this.a = a; }, object, 1);
await check(function getB() { return this.b; }, object);
await check(function setB(b) { this.b = b; }, object, "lala");
await check(function setSomeGlobal() { globalThis.someGlobal = this; }, object);
await check(function localSideEffect() { const date = new Date(); date.setDate(this.a); return date; }, object);
await Protocol.Runtime.disable();
}
]);

View File

@ -0,0 +1,177 @@
Tests that CommandLineAPI is presented only while evaluation.
{
id : <messageId>
result : {
result : {
description : 15
type : number
value : 15
}
}
}
{
id : <messageId>
result : {
result : {
description : 0
type : number
value : 0
}
}
}
setPropertyForMethod()
{
id : <messageId>
result : {
result : {
description : 14
type : number
value : 14
}
}
}
{
id : <messageId>
result : {
result : {
description : 0
type : number
value : 0
}
}
}
{
id : <messageId>
result : {
result : {
description : 42
type : number
value : 42
}
}
}
defineValuePropertyForMethod()
{
id : <messageId>
result : {
result : {
description : 14
type : number
value : 14
}
}
}
{
id : <messageId>
result : {
result : {
description : 0
type : number
value : 0
}
}
}
{
id : <messageId>
result : {
result : {
description : 42
type : number
value : 42
}
}
}
definePropertiesForMethod()
{
id : <messageId>
result : {
result : {
description : 14
type : number
value : 14
}
}
}
{
id : <messageId>
result : {
result : {
description : 0
type : number
value : 0
}
}
}
{
id : <messageId>
result : {
result : {
description : 42
type : number
value : 42
}
}
}
defineAccessorPropertyForMethod()
{
id : <messageId>
result : {
result : {
description : 14
type : number
value : 14
}
}
}
{
id : <messageId>
result : {
result : {
description : 0
type : number
value : 0
}
}
}
{
id : <messageId>
result : {
result : {
description : 42
type : number
value : 42
}
}
}
redefineGetOwnPropertyDescriptors()
{
id : <messageId>
result : {
result : {
description : 14
type : number
value : 14
}
}
}
{
id : <messageId>
result : {
result : {
description : 0
type : number
value : 0
}
}
}
{
id : <messageId>
result : {
result : {
description : 42
type : number
value : 42
}
}
}

View File

@ -0,0 +1,117 @@
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
let {session, contextGroup, Protocol} = InspectorTest.start("Tests that CommandLineAPI is presented only while evaluation.");
contextGroup.addScript(
`
var methods = ["dir","dirxml","profile","profileEnd","clear","table","keys","values","debug","undebug","monitor","unmonitor","inspect","copy"];
var window = this;
function presentedAPIMethods()
{
var methodCount = 0;
for (var method of methods) {
try {
if (eval("window." + method + "&&" + method + ".toString ? " + method + ".toString().indexOf(\\"[native code]\\") !== -1 : false"))
++methodCount;
} catch (e) {
}
}
methodCount += eval("\\"$_\\" in window ? $_ === 239 : false") ? 1 : 0;
return methodCount;
}
function setPropertyForMethod()
{
window.dir = 42;
}
function defineValuePropertyForMethod()
{
Object.defineProperty(window, "dir", { value: 42 });
}
function defineAccessorPropertyForMethod()
{
Object.defineProperty(window, "dir", { set: function() {}, get: function(){ return 42 } });
}
function definePropertiesForMethod()
{
Object.defineProperties(window, { "dir": { set: function() {}, get: function(){ return 42 } }});
}
var builtinGetOwnPropertyDescriptorOnObject;
var builtinGetOwnPropertyDescriptorOnObjectPrototype;
var builtinGetOwnPropertyDescriptorOnWindow;
function redefineGetOwnPropertyDescriptors()
{
builtinGetOwnPropertyDescriptorOnObject = Object.getOwnPropertyDescriptor;
Object.getOwnPropertyDescriptor = function() {}
builtinGetOwnPropertyDescriptorOnObjectPrototype = Object.prototype.getOwnPropertyDescriptor;
Object.prototype.getOwnPropertyDescriptor = function() {}
builtinGetOwnPropertyDescriptorOnWindow = window.getOwnPropertyDescriptor;
window.getOwnPropertyDescriptor = function() {}
}
function restoreGetOwnPropertyDescriptors()
{
Object.getOwnPropertyDescriptor = builtinGetOwnPropertyDescriptorOnObject;
Object.prototype.getOwnPropertyDescriptor = builtinGetOwnPropertyDescriptorOnObjectPrototype;
window.getOwnPropertyDescriptor = builtinGetOwnPropertyDescriptorOnWindow;
}`);
runExpressionAndDumpPresentedMethods("")
.then(dumpLeftMethods)
.then(() => runExpressionAndDumpPresentedMethods("setPropertyForMethod()"))
.then(dumpLeftMethods)
.then(dumpDir)
.then(() => runExpressionAndDumpPresentedMethods("defineValuePropertyForMethod()"))
.then(dumpLeftMethods)
.then(dumpDir)
.then(() => runExpressionAndDumpPresentedMethods("definePropertiesForMethod()"))
.then(dumpLeftMethods)
.then(dumpDir)
.then(() => runExpressionAndDumpPresentedMethods("defineAccessorPropertyForMethod()"))
.then(dumpLeftMethods)
.then(dumpDir)
.then(() => runExpressionAndDumpPresentedMethods("redefineGetOwnPropertyDescriptors()"))
.then(dumpLeftMethods)
.then(dumpDir)
.then(() => evaluate("restoreGetOwnPropertyDescriptors()", false))
.then(InspectorTest.completeTest);
function evaluate(expression, includeCommandLineAPI)
{
return Protocol.Runtime.evaluate({ expression: expression, objectGroup: "console", includeCommandLineAPI: includeCommandLineAPI });
}
function setLastEvaluationResultTo239()
{
return evaluate("239", false);
}
function runExpressionAndDumpPresentedMethods(expression)
{
InspectorTest.log(expression);
return setLastEvaluationResultTo239()
.then(() => evaluate(expression + "; var a = presentedAPIMethods(); a", true))
.then((result) => InspectorTest.logMessage(result));
}
function dumpLeftMethods()
{
// Should always be zero.
return setLastEvaluationResultTo239()
.then(() => evaluate("presentedAPIMethods()", false))
.then((result) => InspectorTest.logMessage(result));
}
function dumpDir()
{
// Should always be presented.
return evaluate("dir", false)
.then((result) => InspectorTest.logMessage(result));
}

View File

@ -0,0 +1,8 @@
Checks that we passed correct arguments in V8InspectorClient::consoleAPIMessage. Note: lines and columns are 1-based.
log: 42 (:1:9)
at (anonymous function) (:1:9)
info: 239 (:13:15)
at b (:13:15)
at a (:15:5)
at consoleTrace (:17:3)
at (anonymous function) (:1:1)

View File

@ -0,0 +1,28 @@
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
let {session, contextGroup, Protocol} = InspectorTest.start('Checks that we passed correct arguments in ' +
'V8InspectorClient::consoleAPIMessage. Note: lines and columns are 1-based.');
contextGroup.addScript(`
function consoleTrace() {
function a() {
function b() {
console.trace(239);
}
b();
}
a();
}
`, 8, 26);
Protocol.Runtime.enable();
utils.setLogConsoleApiMessageCalls(true);
(async function test() {
Protocol.Runtime.evaluate({expression: 'console.log(42)'});
await Protocol.Runtime.onceConsoleAPICalled()
Protocol.Runtime.evaluate({expression: 'consoleTrace()'});
await Protocol.Runtime.onceConsoleAPICalled()
InspectorTest.completeTest();
})();

View File

@ -0,0 +1,719 @@
Checks command line API.
Running test: testKeys
{
id : <messageId>
result : {
result : {
className : Function
description : function keys() { [native code] }
objectId : <objectId>
type : function
}
}
}
{
id : <messageId>
result : {
result : {
type : object
value : [
[0] : a
]
}
}
}
{
id : <messageId>
result : {
result : {
type : object
value : [
[0] : a
]
}
}
}
Running test: testInspect
[object Object]
{
method : Runtime.inspectRequested
params : {
executionContextId : <executionContextId>
hints : {
}
object : {
className : Object
description : Object
objectId : <objectId>
type : object
}
}
}
{
method : Runtime.inspectRequested
params : {
executionContextId : <executionContextId>
hints : {
}
object : {
description : 239
type : number
value : 239
}
}
}
{
method : Runtime.inspectRequested
params : {
executionContextId : <executionContextId>
hints : {
}
object : {
description : -0
type : number
unserializableValue : -0
}
}
}
{
method : Runtime.inspectRequested
params : {
executionContextId : <executionContextId>
hints : {
copyToClipboard : true
}
object : {
type : string
value : hello
}
}
}
{
id : <messageId>
result : {
result : {
type : undefined
}
}
}
{
method : Runtime.inspectRequested
params : {
executionContextId : <executionContextId>
hints : {
}
object : {
className : Object
description : Object
objectId : <objectId>
type : object
}
}
}
Running test: testQueryObjects
{
id : <messageId>
result : {
result : {
className : Function
description : function queryObjects() { [native code] }
objectId : <objectId>
type : function
}
}
}
{
method : Runtime.inspectRequested
params : {
executionContextId : <executionContextId>
hints : {
queryObjects : true
}
object : {
className : Promise
description : Promise
objectId : <objectId>
type : object
}
}
}
Is Promise.prototype: true
{
method : Runtime.inspectRequested
params : {
executionContextId : <executionContextId>
hints : {
queryObjects : true
}
object : {
className : Promise
description : Promise
objectId : <objectId>
type : object
}
}
}
Is Promise.prototype: true
{
method : Runtime.inspectRequested
params : {
executionContextId : <executionContextId>
hints : {
queryObjects : true
}
object : {
className : Object
description : Object
objectId : <objectId>
type : object
}
}
}
Is p: true
{
method : Runtime.inspectRequested
params : {
executionContextId : <executionContextId>
hints : {
queryObjects : true
}
object : {
description : 1
type : number
value : 1
}
}
}
Running test: testEvaluationResult
{
id : <messageId>
result : {
result : {
type : undefined
}
}
}
{
id : <messageId>
result : {
result : {
description : 42
type : number
value : 42
}
}
}
{
id : <messageId>
result : {
result : {
description : 42
type : number
value : 42
}
}
}
{
id : <messageId>
result : {
result : {
description : -0
type : number
unserializableValue : -0
}
}
}
{
id : <messageId>
result : {
result : {
type : object
value : {
}
}
}
}
Running test: testDebug
{
id : <messageId>
result : {
result : {
className : Function
description : function debug() { [native code] }
objectId : <objectId>
type : function
}
}
}
{
id : <messageId>
result : {
result : {
className : Function
description : function undebug() { [native code] }
objectId : <objectId>
type : function
}
}
}
foo (:0:16)
(anonymous) (:0:0)
[
[0] : 5:1
]
debugCommand
foo (:0:16)
(anonymous) (:0:0)
[
[0] : 5:1
]
debugCommand
toUpper (:0:31)
(anonymous) (:0:0)
[
[0] : 5:2
]
debugCommand
callSetTimeout (:0:28)
(anonymous) (:0:0)
[
[0] : 5:3
]
debugCommand
callSetTimeout (:0:28)
(anonymous) (:0:0)
[
[0] : 5:3
]
debugCommand
fromCharCode (:0:40)
(anonymous) (:0:0)
[
[0] : 5:4
]
debugCommand
Running test: testMonitor
{
id : <messageId>
result : {
result : {
className : Function
description : function monitor() { [native code] }
objectId : <objectId>
type : function
}
}
}
{
id : <messageId>
result : {
result : {
className : Function
description : function unmonitor() { [native code] }
objectId : <objectId>
type : function
}
}
}
function foo called
after first call
store functions..
function foo called
after first call
function fromCharCode called with arguments: 1, 2, 3
Running test: testProfile
{
id : <messageId>
result : {
result : {
className : Function
description : function profile() { [native code] }
objectId : <objectId>
type : function
}
}
}
{
id : <messageId>
result : {
result : {
className : Function
description : function profileEnd() { [native code] }
objectId : <objectId>
type : function
}
}
}
{
method : Profiler.consoleProfileStarted
params : {
id : 1
location : {
columnNumber : 1
lineNumber : 1
scriptId : <scriptId>
}
title : 42
}
}
{
method : Profiler.consoleProfileFinished
params : {
id : 1
location : {
columnNumber : 1
lineNumber : 1
scriptId : <scriptId>
}
profile : <profile>
title : 42
}
}
{
method : Profiler.consoleProfileStarted
params : {
id : 2
location : {
columnNumber : 6
lineNumber : 1
scriptId : <scriptId>
}
title : 239
}
}
{
method : Profiler.consoleProfileFinished
params : {
id : 2
location : {
columnNumber : 6
lineNumber : 1
scriptId : <scriptId>
}
profile : <profile>
title : 239
}
}
Running test: testDir
{
id : <messageId>
result : {
result : {
className : Function
description : function dir() { [native code] }
objectId : <objectId>
type : function
}
}
}
{
method : Runtime.consoleAPICalled
params : {
args : [
[0] : {
className : Object
description : Object
objectId : <objectId>
preview : {
description : Object
overflow : false
properties : [
]
type : object
}
type : object
}
]
executionContextId : <executionContextId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 0
functionName :
lineNumber : 0
scriptId : <scriptId>
url :
}
]
}
timestamp : <timestamp>
type : dir
}
}
{
method : Runtime.consoleAPICalled
params : {
args : [
[0] : {
description : 42
type : number
value : 42
}
]
executionContextId : <executionContextId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 0
functionName :
lineNumber : 0
scriptId : <scriptId>
url :
}
]
}
timestamp : <timestamp>
type : dir
}
}
{
method : Runtime.consoleAPICalled
params : {
args : [
[0] : {
className : Object
description : Object
objectId : <objectId>
preview : {
description : Object
overflow : false
properties : [
]
type : object
}
type : object
}
]
executionContextId : <executionContextId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 5
functionName :
lineNumber : 0
scriptId : <scriptId>
url :
}
]
}
timestamp : <timestamp>
type : dir
}
}
Running test: testDirXML
{
id : <messageId>
result : {
result : {
className : Function
description : function dirxml() { [native code] }
objectId : <objectId>
type : function
}
}
}
{
method : Runtime.consoleAPICalled
params : {
args : [
[0] : {
className : Object
description : Object
objectId : <objectId>
preview : {
description : Object
overflow : false
properties : [
]
type : object
}
type : object
}
]
executionContextId : <executionContextId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 0
functionName :
lineNumber : 0
scriptId : <scriptId>
url :
}
]
}
timestamp : <timestamp>
type : dirxml
}
}
{
method : Runtime.consoleAPICalled
params : {
args : [
[0] : {
description : 42
type : number
value : 42
}
]
executionContextId : <executionContextId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 0
functionName :
lineNumber : 0
scriptId : <scriptId>
url :
}
]
}
timestamp : <timestamp>
type : dirxml
}
}
Running test: testTable
{
id : <messageId>
result : {
result : {
className : Function
description : function table() { [native code] }
objectId : <objectId>
type : function
}
}
}
{
method : Runtime.consoleAPICalled
params : {
args : [
[0] : {
className : Object
description : Object
objectId : <objectId>
preview : {
description : Object
overflow : false
properties : [
]
type : object
}
type : object
}
]
executionContextId : <executionContextId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 0
functionName :
lineNumber : 0
scriptId : <scriptId>
url :
}
]
}
timestamp : <timestamp>
type : table
}
}
{
method : Runtime.consoleAPICalled
params : {
args : [
[0] : {
description : 42
type : number
value : 42
}
]
executionContextId : <executionContextId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 0
functionName :
lineNumber : 0
scriptId : <scriptId>
url :
}
]
}
timestamp : <timestamp>
type : table
}
}
Running test: testClear
{
id : <messageId>
result : {
result : {
className : Function
description : function clear() { [native code] }
objectId : <objectId>
type : function
}
}
}
{
method : Runtime.consoleAPICalled
params : {
args : [
[0] : {
type : string
value : console.clear
}
]
executionContextId : <executionContextId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 0
functionName :
lineNumber : 0
scriptId : <scriptId>
url :
}
]
}
timestamp : <timestamp>
type : clear
}
}
{
method : Runtime.consoleAPICalled
params : {
args : [
[0] : {
type : string
value : console.clear
}
]
executionContextId : <executionContextId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 5
functionName :
lineNumber : 0
scriptId : <scriptId>
url :
}
]
}
timestamp : <timestamp>
type : clear
}
}

View File

@ -0,0 +1,134 @@
Tests Command Line API evaluations with throwOnSideEffect.
Expression: console.memory
42
Expression: $_
43
Expression: $0
undefined
Expression: $1
undefined
Expression: $2
undefined
Expression: $3
undefined
Expression: $4
undefined
Method: console.debug
EvalError: Possible side-effect in debug-evaluate
function debug() { [native code] }
Method: console.error
EvalError: Possible side-effect in debug-evaluate
function error() { [native code] }
Method: console.info
EvalError: Possible side-effect in debug-evaluate
function info() { [native code] }
Method: console.log
EvalError: Possible side-effect in debug-evaluate
function log() { [native code] }
Method: console.warn
EvalError: Possible side-effect in debug-evaluate
function warn() { [native code] }
Method: console.dir
EvalError: Possible side-effect in debug-evaluate
function dir() { [native code] }
Method: console.dirxml
EvalError: Possible side-effect in debug-evaluate
function dirxml() { [native code] }
Method: console.table
EvalError: Possible side-effect in debug-evaluate
function table() { [native code] }
Method: console.trace
EvalError: Possible side-effect in debug-evaluate
function trace() { [native code] }
Method: console.group
EvalError: Possible side-effect in debug-evaluate
function group() { [native code] }
Method: console.groupEnd
EvalError: Possible side-effect in debug-evaluate
function groupEnd() { [native code] }
Method: console.groupCollapsed
EvalError: Possible side-effect in debug-evaluate
function groupCollapsed() { [native code] }
Method: console.clear
EvalError: Possible side-effect in debug-evaluate
function clear() { [native code] }
Method: console.count
EvalError: Possible side-effect in debug-evaluate
function count() { [native code] }
Method: console.assert
EvalError: Possible side-effect in debug-evaluate
function assert() { [native code] }
Method: console.profile
EvalError: Possible side-effect in debug-evaluate
function profile() { [native code] }
Method: console.profileEnd
EvalError: Possible side-effect in debug-evaluate
function profileEnd() { [native code] }
Method: console.time
EvalError: Possible side-effect in debug-evaluate
function time() { [native code] }
Method: console.timeEnd
EvalError: Possible side-effect in debug-evaluate
function timeEnd() { [native code] }
Method: debug
EvalError: Possible side-effect in debug-evaluate
function debug(function, condition) { [Command Line API] }
Method: undebug
EvalError: Possible side-effect in debug-evaluate
function undebug(function) { [Command Line API] }
Method: monitor
EvalError: Possible side-effect in debug-evaluate
function monitor(function) { [Command Line API] }
Method: unmonitor
EvalError: Possible side-effect in debug-evaluate
function unmonitor(function) { [Command Line API] }
Method: keys
Array(2)
function keys(object) { [Command Line API] }
Method: values
Array(2)
function values(object) { [Command Line API] }
Method: inspect
EvalError: Possible side-effect in debug-evaluate
function inspect(object) { [Command Line API] }
Method: copy
EvalError: Possible side-effect in debug-evaluate
function copy(value) { [Command Line API] }
Method: queryObjects
EvalError: Possible side-effect in debug-evaluate
function queryObjects(constructor) { [Command Line API] }

View File

@ -0,0 +1,83 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
let {session, contextGroup, Protocol} = InspectorTest.start(
'Tests Command Line API evaluations with throwOnSideEffect.');
session.setupScriptMap();
contextGroup.addScript(`
function f() {
}
var obj = {x: 1, y: 2};
//# sourceURL=test.js`);
Protocol.Runtime.enable();
Protocol.Debugger.enable();
(async function() {
utils.setMemoryInfoForTest(42);
await testExpression('console.memory');
await Protocol.Runtime.evaluate(
{expression: '43', objectGroup: 'console', includeCommandLineAPI: true});
await testExpression('$_');
await testExpression('$0');
await testExpression('$1');
await testExpression('$2');
await testExpression('$3');
await testExpression('$4');
await testMethod('console.debug');
await testMethod('console.error');
await testMethod('console.info');
await testMethod('console.log');
await testMethod('console.warn');
await testMethod('console.dir');
await testMethod('console.dirxml');
await testMethod('console.table');
await testMethod('console.trace');
await testMethod('console.group');
await testMethod('console.groupEnd');
await testMethod('console.groupCollapsed');
await testMethod('console.clear');
await testMethod('console.count');
await testMethod('console.assert');
await testMethod('console.profile');
await testMethod('console.profileEnd');
await testMethod('console.time');
await testMethod('console.timeEnd');
await testMethod('debug', ['f']);
await testMethod('undebug', ['f']);
await testMethod('monitor');
await testMethod('unmonitor');
await testMethod('keys', ['obj']);
await testMethod('values', ['obj']);
await testMethod('inspect');
await testMethod('copy', ['1']);
await testMethod('queryObjects', ['Array']);
InspectorTest.completeTest();
async function testExpression(expression) {
InspectorTest.log(`\nExpression: ${expression}`);
await evaluateAndPrint(expression);
}
async function testMethod(method, args = []) {
InspectorTest.log(`\nMethod: ${method}`);
await evaluateAndPrint(`${method}(${args.join(', ')})`);
await evaluateAndPrint(`${method}.toString()`);
}
async function evaluateAndPrint(expression) {
const result = (await Protocol.Runtime.evaluate({
expression,
throwOnSideEffect: true,
includeCommandLineAPI: true
})).result;
if (result.exceptionDetails)
InspectorTest.logMessage(result.exceptionDetails.exception.description);
else if (result.result)
InspectorTest.logMessage(
result.result.description || result.result.value ||
result.result.type);
}
})();

View File

@ -0,0 +1,266 @@
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
let {session, contextGroup, Protocol} = InspectorTest.start('Checks command line API.');
InspectorTest.runAsyncTestSuite([
async function testKeys() {
InspectorTest.logMessage(await Protocol.Runtime.evaluate({
expression: 'keys', includeCommandLineAPI: true}));
InspectorTest.logMessage(await Protocol.Runtime.evaluate({
expression: 'keys({a : 1})', includeCommandLineAPI: true, returnByValue: true}));
Protocol.Runtime.evaluate({expression: 'this.keys = keys', includeCommandLineAPI: true});
InspectorTest.logMessage(await Protocol.Runtime.evaluate({
expression: 'this.keys({a : 1})', returnByValue: true}));
},
async function testInspect() {
InspectorTest.log(await Protocol.Runtime.evaluate({expression: 'inspect', includeCommandLineAPI: true}));
await Protocol.Runtime.enable();
Protocol.Runtime.onInspectRequested(InspectorTest.logMessage);
await Protocol.Runtime.evaluate({expression: 'inspect({})', includeCommandLineAPI: true});
await Protocol.Runtime.evaluate({expression: 'inspect(239)', includeCommandLineAPI: true});
await Protocol.Runtime.evaluate({expression: 'inspect(-0)', includeCommandLineAPI: true});
await Protocol.Runtime.evaluate({expression: 'copy(\'hello\')', includeCommandLineAPI: true});
InspectorTest.logMessage(await Protocol.Runtime.evaluate({expression: '$0', includeCommandLineAPI: true}));
Protocol.Runtime.evaluate({expression: 'this.inspect = inspect', includeCommandLineAPI: true});
await Protocol.Runtime.evaluate({expression: 'this.inspect({})'});
Protocol.Runtime.onInspectRequested(null);
await Protocol.Runtime.disable();
},
async function testQueryObjects() {
InspectorTest.logMessage(await Protocol.Runtime.evaluate({expression: 'queryObjects', includeCommandLineAPI: true}));
await Protocol.Runtime.enable();
let {result:{result:{objectId}}} = await Protocol.Runtime.evaluate({expression: 'Promise.prototype'});
Protocol.Runtime.evaluate({expression: 'queryObjects(Promise)', includeCommandLineAPI: true});
let request = await Protocol.Runtime.onceInspectRequested();
InspectorTest.logMessage(request);
InspectorTest.logMessage('Is Promise.prototype: ' + await isEqual(objectId, request.params.object.objectId));
Protocol.Runtime.evaluate({expression: 'queryObjects(Promise.prototype)', includeCommandLineAPI: true});
request = await Protocol.Runtime.onceInspectRequested();
InspectorTest.logMessage(request);
InspectorTest.logMessage('Is Promise.prototype: ' + await isEqual(objectId, request.params.object.objectId));
({result:{result:{objectId}}} = await Protocol.Runtime.evaluate({expression:'p = {a:1}'}));
Protocol.Runtime.evaluate({expression: 'queryObjects(p)', includeCommandLineAPI: true});
request = await Protocol.Runtime.onceInspectRequested();
InspectorTest.logMessage(request);
InspectorTest.logMessage('Is p: ' + await isEqual(objectId, request.params.object.objectId));
Protocol.Runtime.evaluate({expression: 'queryObjects(1)', includeCommandLineAPI: true});
InspectorTest.logMessage(await Protocol.Runtime.onceInspectRequested());
await Protocol.Runtime.disable();
},
async function testEvaluationResult() {
InspectorTest.logMessage(await Protocol.Runtime.evaluate({expression: '$_', includeCommandLineAPI: true}));
await Protocol.Runtime.evaluate({expression: '42', objectGroup: 'console', includeCommandLineAPI: true});
InspectorTest.logMessage(await Protocol.Runtime.evaluate({expression: '$_', includeCommandLineAPI: true}));
await Protocol.Runtime.evaluate({expression: '239', includeCommandLineAPI: true});
InspectorTest.logMessage(await Protocol.Runtime.evaluate({expression: '$_', includeCommandLineAPI: true}));
await Protocol.Runtime.evaluate({expression: '-0', objectGroup: 'console', includeCommandLineAPI: true});
InspectorTest.logMessage(await Protocol.Runtime.evaluate({expression: '$_', includeCommandLineAPI: true}));
await Protocol.Runtime.evaluate({expression: '({})', objectGroup: 'console', includeCommandLineAPI: true});
InspectorTest.logMessage(await Protocol.Runtime.evaluate({expression: '$_', includeCommandLineAPI: true, returnByValue: true}));
},
async function testDebug() {
session.setupScriptMap();
await Protocol.Debugger.enable();
InspectorTest.logMessage(await Protocol.Runtime.evaluate({expression: 'debug', includeCommandLineAPI: true}));
InspectorTest.logMessage(await Protocol.Runtime.evaluate({expression: 'undebug', includeCommandLineAPI: true}));
await Protocol.Runtime.evaluate({expression: 'function foo() {}'});
await Protocol.Runtime.evaluate({expression: 'debug(foo)', includeCommandLineAPI: true});
Protocol.Runtime.evaluate({ expression: 'foo()'});
let message = await Protocol.Debugger.oncePaused();
session.logCallFrames(message.params.callFrames);
InspectorTest.logMessage(message.params.hitBreakpoints);
InspectorTest.logMessage(message.params.reason);
await Protocol.Debugger.resume();
await Protocol.Runtime.evaluate({expression: 'undebug(foo)', includeCommandLineAPI: true});
await Protocol.Runtime.evaluate({ expression: 'foo()'});
Protocol.Runtime.evaluate({
expression: 'this.debug = debug; this.undebug = undebug;', includeCommandLineAPI: true});
await Protocol.Runtime.evaluate({expression: 'this.debug(foo)'});
Protocol.Runtime.evaluate({ expression: 'foo()'});
message = await Protocol.Debugger.oncePaused();
session.logCallFrames(message.params.callFrames);
InspectorTest.logMessage(message.params.hitBreakpoints);
InspectorTest.logMessage(message.params.reason);
await Protocol.Debugger.resume();
await Protocol.Runtime.evaluate({expression: 'this.undebug(foo)'});
await Protocol.Runtime.evaluate({expression: 'foo()'});
// Test builtin.
await Protocol.Runtime.evaluate({expression: 'function toUpper(x) { return x.toUpperCase() }'});
await Protocol.Runtime.evaluate({expression: 'debug(String.prototype.toUpperCase)', includeCommandLineAPI: true});
Protocol.Runtime.evaluate({ expression: 'toUpper("first call")'});
message = await Protocol.Debugger.oncePaused();
session.logCallFrames(message.params.callFrames);
InspectorTest.logMessage(message.params.hitBreakpoints);
InspectorTest.logMessage(message.params.reason);
await Protocol.Debugger.resume();
await Protocol.Runtime.evaluate({expression: 'undebug(String.prototype.toUpperCase)', includeCommandLineAPI: true});
await Protocol.Runtime.evaluate({ expression: 'toUpper("second call")'});
// Test API callback.
await Protocol.Runtime.evaluate({expression: 'function callSetTimeout() { setTimeout(function(){}, 0) }'});
await Protocol.Runtime.evaluate({expression: 'debug(setTimeout)', includeCommandLineAPI: true});
Protocol.Runtime.evaluate({ expression: 'callSetTimeout()'});
message = await Protocol.Debugger.oncePaused();
session.logCallFrames(message.params.callFrames);
InspectorTest.logMessage(message.params.hitBreakpoints);
InspectorTest.logMessage(message.params.reason);
let breakpointId = message.params.hitBreakpoints[0];
await Protocol.Debugger.resume();
await Protocol.Runtime.evaluate({expression: 'undebug(setTimeout)', includeCommandLineAPI: true});
await Protocol.Runtime.evaluate({ expression: 'callSetTimeout()'});
// Test remove break via protocol.
await Protocol.Runtime.evaluate({expression: 'function callSetTimeout() { setTimeout(function(){}, 0) }'});
await Protocol.Runtime.evaluate({expression: 'debug(setTimeout)', includeCommandLineAPI: true});
Protocol.Runtime.evaluate({ expression: 'callSetTimeout()'});
message = await Protocol.Debugger.oncePaused();
session.logCallFrames(message.params.callFrames);
InspectorTest.logMessage(message.params.hitBreakpoints);
InspectorTest.logMessage(message.params.reason);
await Protocol.Debugger.resume();
await Protocol.Debugger.removeBreakpoint({breakpointId});
await Protocol.Runtime.evaluate({ expression: 'callSetTimeout()'});
// Test condition.
await Protocol.Runtime.evaluate({expression: 'function fromCharCode(...args) { String.fromCharCode(...args) }'});
await Protocol.Runtime.evaluate({expression: 'debug(String.fromCharCode, "arguments.length == 3")'});
Protocol.Runtime.evaluate({ expression: 'fromCharCode("1", "2", "3")'});
message = await Protocol.Debugger.oncePaused();
session.logCallFrames(message.params.callFrames);
InspectorTest.logMessage(message.params.hitBreakpoints);
InspectorTest.logMessage(message.params.reason);
await Protocol.Runtime.evaluate({expression: 'undebug(String.fromCharCode)'});
await Protocol.Runtime.evaluate({ expression: 'fromCharCode()'});
await Protocol.Debugger.disable();
},
async function testMonitor() {
await Protocol.Debugger.enable();
await Protocol.Runtime.enable();
Protocol.Runtime.onConsoleAPICalled(message => InspectorTest.log(message.params.args[0].value));
InspectorTest.logMessage(await Protocol.Runtime.evaluate({expression: 'monitor', includeCommandLineAPI: true}));
InspectorTest.logMessage(await Protocol.Runtime.evaluate({expression: 'unmonitor', includeCommandLineAPI: true}));
await Protocol.Runtime.evaluate({expression: 'function foo() {}'});
await Protocol.Runtime.evaluate({expression: 'monitor(foo)', includeCommandLineAPI: true});
Protocol.Runtime.evaluate({ expression: 'foo(); console.log(\'after first call\')'});
await Protocol.Runtime.evaluate({expression: 'unmonitor(foo)', includeCommandLineAPI: true});
await Protocol.Runtime.evaluate({ expression: 'foo()'});
Protocol.Runtime.evaluate({
expression: 'console.log(\'store functions..\'); this.monitor = monitor; this.unmonitor = unmonitor;', includeCommandLineAPI: true});
await Protocol.Runtime.evaluate({expression: 'this.monitor(foo)'});
Protocol.Runtime.evaluate({ expression: 'foo(); console.log(\'after first call\')'});
await Protocol.Runtime.evaluate({expression: 'this.unmonitor(foo)'});
await Protocol.Runtime.evaluate({ expression: 'foo()'});
// Test builtin.
await Protocol.Runtime.evaluate({expression: 'function fromCharCode(...args) { String.fromCharCode(...args) }'});
await Protocol.Runtime.evaluate({expression: 'monitor(String.fromCharCode)'});
Protocol.Runtime.evaluate({ expression: 'fromCharCode("1", "2", "3")'});
await Protocol.Runtime.evaluate({expression: 'unmonitor(String.fromCharCode)'});
await Protocol.Runtime.evaluate({ expression: 'fromCharCode()'});
Protocol.Runtime.onConsoleAPICalled(null);
await Protocol.Debugger.disable();
await Protocol.Runtime.disable();
},
async function testProfile() {
await Protocol.Profiler.enable();
InspectorTest.logMessage(await Protocol.Runtime.evaluate({expression: 'profile', includeCommandLineAPI: true}));
InspectorTest.logMessage(await Protocol.Runtime.evaluate({expression: 'profileEnd', includeCommandLineAPI: true}));
Protocol.Runtime.evaluate({expression: 'profile(42)', includeCommandLineAPI: true});
InspectorTest.logMessage(await Protocol.Profiler.onceConsoleProfileStarted());
Protocol.Runtime.evaluate({expression: 'profileEnd(42)', includeCommandLineAPI: true});
let message = await Protocol.Profiler.onceConsoleProfileFinished();
message.params.profile = '<profile>';
InspectorTest.logMessage(message);
Protocol.Runtime.evaluate({
expression: 'this.profile = profile; this.profileEnd = profileEnd;', includeCommandLineAPI: true});
Protocol.Runtime.evaluate({expression: 'this.profile(239)'});
InspectorTest.logMessage(await Protocol.Profiler.onceConsoleProfileStarted());
Protocol.Runtime.evaluate({expression: 'this.profileEnd(239)'});
message = await Protocol.Profiler.onceConsoleProfileFinished();
message.params.profile = '<profile>';
InspectorTest.logMessage(message);
await Protocol.Profiler.disable();
},
async function testDir() {
InspectorTest.logMessage(await Protocol.Runtime.evaluate({expression: 'dir', includeCommandLineAPI: true}));
await Protocol.Runtime.enable();
Protocol.Runtime.evaluate({expression: 'dir({})', includeCommandLineAPI: true});
InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());
Protocol.Runtime.evaluate({expression: 'dir(42)', includeCommandLineAPI: true});
InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());
Protocol.Runtime.evaluate({expression: 'this.dir = dir', includeCommandLineAPI: true});
Protocol.Runtime.evaluate({expression: 'this.dir({})'});
InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());
await Protocol.Runtime.disable();
},
async function testDirXML() {
InspectorTest.logMessage(await Protocol.Runtime.evaluate({expression: 'dirxml', includeCommandLineAPI: true}));
await Protocol.Runtime.enable();
Protocol.Runtime.evaluate({expression: 'dirxml({})', includeCommandLineAPI: true});
InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());
Protocol.Runtime.evaluate({expression: 'dirxml(42)', includeCommandLineAPI: true});
InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());
await Protocol.Runtime.disable();
},
async function testTable() {
InspectorTest.logMessage(await Protocol.Runtime.evaluate({expression: 'table', includeCommandLineAPI: true}));
await Protocol.Runtime.enable();
Protocol.Runtime.evaluate({expression: 'table({})', includeCommandLineAPI: true});
InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());
Protocol.Runtime.evaluate({expression: 'table(42)', includeCommandLineAPI: true});
InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());
await Protocol.Runtime.disable();
},
async function testClear() {
InspectorTest.logMessage(await Protocol.Runtime.evaluate({expression: 'clear', includeCommandLineAPI: true}));
await Protocol.Runtime.enable();
Protocol.Runtime.evaluate({expression: 'clear()', includeCommandLineAPI: true});
InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());
Protocol.Runtime.evaluate({expression: 'this.clear = clear', includeCommandLineAPI: true});
Protocol.Runtime.evaluate({expression: 'this.clear()'});
InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());
await Protocol.Runtime.disable();
}
]);
async function isEqual(objectId1, objectId2) {
return (await Protocol.Runtime.callFunctionOn({
objectId: objectId1,
functionDeclaration: 'function(arg){return this === arg;}',
returnByValue: true,
arguments: [{objectId: objectId2}]
})).result.result.value;
}

View File

@ -0,0 +1,67 @@
Tests Runtime.compileScript
Compiling script: foo1.js
persist: false
compilation result:
{
id : <messageId>
result : {
exceptionDetails : {
columnNumber : 3
exception : {
className : SyntaxError
description : SyntaxError: Unexpected end of input
objectId : <objectId>
subtype : error
type : object
}
exceptionId : <exceptionId>
lineNumber : 1
scriptId : <scriptId>
text : Uncaught
}
}
}
-----
Compiling script: foo2.js
persist: true
Debugger.scriptParsed: foo2.js
compilation result:
{
id : <messageId>
result : {
scriptId : <scriptId>
}
}
-----
Compiling script: foo3.js
persist: false
compilation result:
{
id : <messageId>
result : {
}
}
-----
Compiling script: foo4.js
persist: false
compilation result:
{
id : <messageId>
result : {
exceptionDetails : {
columnNumber : 13
exception : {
className : SyntaxError
description : SyntaxError: Unexpected identifier 'f'
objectId : <objectId>
subtype : error
type : object
}
exceptionId : <exceptionId>
lineNumber : 0
scriptId : <scriptId>
text : Uncaught
}
}
}
-----

View File

@ -0,0 +1,52 @@
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
let {session, contextGroup, Protocol} = InspectorTest.start('Tests Runtime.compileScript');
var executionContextId;
Protocol.Debugger.enable().then(onDebuggerEnabled);
function onDebuggerEnabled()
{
Protocol.Runtime.enable();
Protocol.Debugger.onScriptParsed(onScriptParsed);
Protocol.Runtime.onExecutionContextCreated(onExecutionContextCreated);
}
function onScriptParsed(messageObject)
{
if (!messageObject.params.url)
return;
InspectorTest.log("Debugger.scriptParsed: " + messageObject.params.url);
}
function onExecutionContextCreated(messageObject)
{
executionContextId = messageObject.params.context.id;
testCompileScript("\n (", false, "foo1.js")
.then(() => testCompileScript("239", true, "foo2.js"))
.then(() => testCompileScript("239", false, "foo3.js"))
.then(() => testCompileScript("testfunction f()\n{\n return 0;\n}\n", false, "foo4.js"))
.then(() => InspectorTest.completeTest());
}
function testCompileScript(expression, persistScript, sourceURL)
{
InspectorTest.log("Compiling script: " + sourceURL);
InspectorTest.log(" persist: " + persistScript);
return Protocol.Runtime.compileScript({
expression: expression,
sourceURL: sourceURL,
persistScript: persistScript,
executionContextId: executionContextId
}).then(onCompiled);
function onCompiled(messageObject)
{
InspectorTest.log("compilation result: ");
InspectorTest.logMessage(messageObject);
InspectorTest.log("-----");
}
}

View File

@ -0,0 +1,5 @@
Check that console.log is reported through Console domain as well.
api call: 42
api call: abc
console message: 42
console message: abc

View File

@ -0,0 +1,37 @@
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
let {session, contextGroup, Protocol} = InspectorTest.start("Check that console.log is reported through Console domain as well.");
var expectedMessages = 4;
var messages = [];
Protocol.Runtime.onConsoleAPICalled(consoleAPICalled);
Protocol.Console.onMessageAdded(messageAdded);
Protocol.Runtime.enable();
Protocol.Console.enable();
Protocol.Runtime.evaluate({ "expression": "console.log(42)" });
Protocol.Runtime.evaluate({ "expression": "console.error('abc')" });
function consoleAPICalled(result)
{
messages.push("api call: " + result.params.args[0].value);
if (!(--expectedMessages))
done();
}
function messageAdded(result)
{
messages.push("console message: " + result.params.message.text);
if (!(--expectedMessages))
done();
}
function done()
{
messages.sort();
for (var message of messages)
InspectorTest.log(message);
InspectorTest.completeTest();
}

View File

@ -0,0 +1,147 @@
Checks that console.assert works and points to correct call frame.
{
method : Runtime.consoleAPICalled
params : {
args : [
[0] : {
type : string
value : console.assert
}
]
executionContextId : <executionContextId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 10
functionName : testFunction
lineNumber : 4
scriptId : <scriptId>
url : test.js
}
[1] : {
columnNumber : 0
functionName :
lineNumber : 0
scriptId : <scriptId>
url : evaluate.js
}
]
}
timestamp : <timestamp>
type : assert
}
}
{
method : Runtime.consoleAPICalled
params : {
args : [
[0] : {
description : 1
type : number
value : 1
}
]
executionContextId : <executionContextId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 10
functionName : testFunction
lineNumber : 5
scriptId : <scriptId>
url : test.js
}
[1] : {
columnNumber : 0
functionName :
lineNumber : 0
scriptId : <scriptId>
url : evaluate.js
}
]
}
timestamp : <timestamp>
type : assert
}
}
{
method : Runtime.consoleAPICalled
params : {
args : [
[0] : {
description : 1
type : number
value : 1
}
[1] : {
description : 2
type : number
value : 2
}
]
executionContextId : <executionContextId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 10
functionName : testFunction
lineNumber : 6
scriptId : <scriptId>
url : test.js
}
[1] : {
columnNumber : 0
functionName :
lineNumber : 0
scriptId : <scriptId>
url : evaluate.js
}
]
}
timestamp : <timestamp>
type : assert
}
}
{
method : Runtime.consoleAPICalled
params : {
args : [
[0] : {
type : string
value : console.assert
}
]
executionContextId : <executionContextId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 10
functionName : testFunction
lineNumber : 7
scriptId : <scriptId>
url : test.js
}
[1] : {
columnNumber : 0
functionName :
lineNumber : 0
scriptId : <scriptId>
url : evaluate.js
}
]
}
timestamp : <timestamp>
type : assert
}
}
{
id : <messageId>
result : {
result : {
className : Function
description : function assert() { [native code] }
objectId : <objectId>
type : function
}
}
}

View File

@ -0,0 +1,24 @@
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
let {session, contextGroup, Protocol} = InspectorTest.start("Checks that console.assert works and points to correct call frame.");
contextGroup.addScript(`
function testFunction() {
Function.prototype.apply = () => console.error('Should never call this');
console.assert(true);
console.assert(false);
console.assert(false, 1);
console.assert(false, 1, 2);
console.assert();
return console.assert;
}
//# sourceURL=test.js`);
Protocol.Runtime.onConsoleAPICalled(InspectorTest.logMessage);
Protocol.Runtime.enable();
Protocol.Runtime.evaluate({
expression: "testFunction()//# sourceURL=evaluate.js" })
.then(InspectorTest.logMessage)
.then(InspectorTest.completeTest);

View File

@ -0,0 +1,96 @@
Tests console.context
Running test: testConsoleContextMethod
console.context description:
{
className : Function
description : function context() { [native code] }
objectId : <objectId>
type : function
}
console.context() methods:
[
[0] : assert
[1] : clear
[2] : count
[3] : countReset
[4] : debug
[5] : dir
[6] : dirXml
[7] : error
[8] : group
[9] : groupCollapsed
[10] : groupEnd
[11] : info
[12] : log
[13] : profile
[14] : profileEnd
[15] : table
[16] : time
[17] : timeEnd
[18] : timeLog
[19] : timeStamp
[20] : trace
[21] : warn
]
Running test: testDefaultConsoleContext
undefined
undefined
undefined
Running test: testAnonymousConsoleContext
anonymous#2
anonymous#3
anonymous#4
Running test: testNamedConsoleContext
named-context#6
named-context#6
named-context#6
Running test: testTwoConsoleContextsWithTheSameName
named-context#7
named-context#8
Running test: testConsoleCountInDifferentConsoleContexts
[
[0] : {
type : string
value : 239: 1
}
]
[
[0] : {
type : string
value : 239: 1
}
]
Running test: testConsoleCountForNamedConsoleContext
[
[0] : {
type : string
value : 239: 1
}
]
[
[0] : {
type : string
value : 239: 2
}
]
Running test: testConsoleTimeInDifferentConsoleContexts
[
[0] : {
type : string
value : foo: 1 ms
}
]
[
[0] : {
type : string
value : foo: 2 ms
}
]

View File

@ -0,0 +1,139 @@
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
let {session, contextGroup, Protocol} = InspectorTest.start('Tests console.context');
InspectorTest.runAsyncTestSuite([
async function testConsoleContextMethod() {
InspectorTest.log('console.context description:');
var {result:{result}} = await Protocol.Runtime.evaluate({
expression: 'console.context'});
InspectorTest.logMessage(result);
// Enumerate the methods alpha-sorted to make the test
// independent of the (unspecified) enumeration order
// of console.context() methods.
InspectorTest.log('console.context() methods:');
var {result: {result: {value}}} = await Protocol.Runtime.evaluate({
expression: 'Object.keys(console.context()).sort()',
returnByValue: true
});
InspectorTest.logMessage(value);
},
async function testDefaultConsoleContext() {
await Protocol.Runtime.enable();
Protocol.Runtime.evaluate({expression: 'console.log(239)'});
var {params:{context}} = await Protocol.Runtime.onceConsoleAPICalled();
InspectorTest.log(context);
Protocol.Runtime.evaluate({expression: 'console.info(239)'});
var {params:{context}} = await Protocol.Runtime.onceConsoleAPICalled();
InspectorTest.log(context);
Protocol.Runtime.evaluate({expression: 'console.debug(239)'});
var {params:{context}} = await Protocol.Runtime.onceConsoleAPICalled();
InspectorTest.log(context);
await Protocol.Runtime.evaluate({expression: 'console.clear()'});
await Protocol.Runtime.disable();
},
async function testAnonymousConsoleContext() {
await Protocol.Runtime.enable();
Protocol.Runtime.evaluate({expression: 'console.context().log(239)'});
var {params:{context}} = await Protocol.Runtime.onceConsoleAPICalled();
InspectorTest.log(context);
Protocol.Runtime.evaluate({expression: 'console.context().info(239)'});
var {params:{context}} = await Protocol.Runtime.onceConsoleAPICalled();
InspectorTest.log(context);
Protocol.Runtime.evaluate({expression: 'console.context().debug(239)'});
var {params:{context}} = await Protocol.Runtime.onceConsoleAPICalled();
InspectorTest.log(context);
await Protocol.Runtime.evaluate({expression: 'console.context().clear()'});
await Protocol.Runtime.disable();
},
async function testNamedConsoleContext() {
await Protocol.Runtime.enable();
Protocol.Runtime.evaluate({expression: `
var context = console.context('named-context');
context.log(239);
context.info(239);
context.debug(239);
`});
var {params:{context}} = await Protocol.Runtime.onceConsoleAPICalled();
InspectorTest.log(context);
var {params:{context}} = await Protocol.Runtime.onceConsoleAPICalled();
InspectorTest.log(context);
var {params:{context}} = await Protocol.Runtime.onceConsoleAPICalled();
InspectorTest.log(context);
await Protocol.Runtime.evaluate({expression: 'console.clear()'});
await Protocol.Runtime.disable();
},
async function testTwoConsoleContextsWithTheSameName() {
await Protocol.Runtime.enable();
Protocol.Runtime.evaluate({expression: 'console.context(\'named-context\').log(239)'});
var {params:{context}} = await Protocol.Runtime.onceConsoleAPICalled();
InspectorTest.log(context);
Protocol.Runtime.evaluate({expression: 'console.context(\'named-context\').log(239)'});
var {params:{context}} = await Protocol.Runtime.onceConsoleAPICalled();
InspectorTest.log(context);
await Protocol.Runtime.evaluate({expression: 'console.clear()'});
await Protocol.Runtime.disable();
},
async function testConsoleCountInDifferentConsoleContexts() {
await Protocol.Runtime.enable();
Protocol.Runtime.evaluate({expression: 'console.context(\'named-context\').count(239)'});
var {params:{args}} = await Protocol.Runtime.onceConsoleAPICalled();
InspectorTest.logMessage(args);
Protocol.Runtime.evaluate({expression: 'console.context(\'named-context\').count(239)'});
var {params:{args}} = await Protocol.Runtime.onceConsoleAPICalled();
InspectorTest.logMessage(args);
await Protocol.Runtime.evaluate({expression: 'console.clear()'});
await Protocol.Runtime.disable();
},
async function testConsoleCountForNamedConsoleContext() {
await Protocol.Runtime.enable();
Protocol.Runtime.evaluate({expression: `
var context = console.context('named-context');
context.count(239);
context.count(239);
`});
var {params:{args}} = await Protocol.Runtime.onceConsoleAPICalled();
InspectorTest.logMessage(args);
var {params:{args}} = await Protocol.Runtime.onceConsoleAPICalled();
InspectorTest.logMessage(args);
await Protocol.Runtime.evaluate({expression: 'console.clear()'});
await Protocol.Runtime.disable();
},
async function testConsoleTimeInDifferentConsoleContexts() {
await Protocol.Runtime.enable();
await Protocol.Runtime.evaluate({
expression: `globalThis.context = console.context('named-context')`,
});
utils.setCurrentTimeMSForTest(0.0);
await Protocol.Runtime.evaluate({
expression: `context.time('foo'); console.time('foo');`,
});
utils.setCurrentTimeMSForTest(1.0);
await Promise.all([
Protocol.Runtime.evaluate({
expression: `console.timeEnd('foo')`,
}),
Protocol.Runtime.onceConsoleAPICalled().then(
({params: {args}}) => InspectorTest.logMessage(args)),
]);
utils.setCurrentTimeMSForTest(2.0);
await Promise.all([
Protocol.Runtime.evaluate({
expression: `context.timeEnd('foo')`,
}),
Protocol.Runtime.onceConsoleAPICalled().then(
({params: {args}}) => InspectorTest.logMessage(args)),
]);
await Protocol.Runtime.disable();
}
]);

View File

@ -0,0 +1,25 @@
Test for default label with console.count() and console.countReset()
[
[0] : {
type : string
value : default: 2
}
]
[
[0] : {
type : string
value : default: 1
}
]
[
[0] : {
type : string
value : default: 2
}
]
[
[0] : {
type : string
value : default: 1
}
]

View File

@ -0,0 +1,43 @@
// Copyright 2024 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
const {session, contextGroup, Protocol} = InspectorTest.start(
'Test for default label with console.count() and console.countReset()');
(async function test() {
await Protocol.Runtime.enable();
await Protocol.Runtime.evaluate({expression: `console.count(undefined)`});
await Promise.all([
Protocol.Runtime.evaluate({expression: `console.count(undefined)`}),
Protocol.Runtime.onceConsoleAPICalled().then(logArgs),
]);
await Protocol.Runtime.evaluate(
{expression: `console.countReset(undefined)`});
await Promise.all([
Protocol.Runtime.evaluate({expression: `console.count(undefined)`}),
Protocol.Runtime.onceConsoleAPICalled().then(logArgs),
]);
await Protocol.Runtime.evaluate(
{expression: `console.countReset(undefined)`});
await Protocol.Runtime.evaluate({expression: `console.count()`});
await Promise.all([
Protocol.Runtime.evaluate({expression: `console.count()`}),
Protocol.Runtime.onceConsoleAPICalled().then(logArgs),
]);
await Protocol.Runtime.evaluate({expression: `console.countReset()`});
await Promise.all([
Protocol.Runtime.evaluate({expression: `console.count()`}),
Protocol.Runtime.onceConsoleAPICalled().then(logArgs),
]);
await Protocol.Runtime.evaluate({expression: `console.countReset()`});
await Protocol.Runtime.disable();
InspectorTest.completeTest();
})()
function logArgs(message) {
InspectorTest.logMessage(message.params.args);
}

View File

@ -0,0 +1,700 @@
Test for console formatting
Running test: testFloatFormatter
Testing console.debug('%f', 3.1415)...
debug[
[0] : {
type : string
value : %f
}
[1] : {
description : 3.1415
type : number
value : 3.1415
}
]
Testing console.error('%f', '3e2')...
error[
[0] : {
type : string
value : %f
}
[1] : {
description : 300
type : number
value : 300
}
]
Testing console.info('%f', Symbol('1.1'))...
info[
[0] : {
type : string
value : %f
}
[1] : {
description : NaN
type : number
unserializableValue : NaN
}
]
Testing console.log('%f', {toString() { return '42'; }})...
log[
[0] : {
type : string
value : %f
}
[1] : {
description : 42
type : number
value : 42
}
]
Testing console.trace('%f', {[Symbol.toPrimitive]() { return 2.78; }})...
trace[
[0] : {
type : string
value : %f
}
[1] : {
description : 2.78
type : number
value : 2.78
}
]
Testing console.warn('%f', {toString() { throw new Error(); }})...
{
columnNumber : 33
exception : {
className : Error
description : Error at Object.toString (<anonymous>:1:40) at parseFloat (<anonymous>) at console.warn (<anonymous>) at <anonymous>:1:9
objectId : <objectId>
subtype : error
type : object
}
exceptionId : <exceptionId>
lineNumber : 0
scriptId : <scriptId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 39
functionName : toString
lineNumber : 0
scriptId : <scriptId>
url :
}
[1] : {
columnNumber : 8
functionName :
lineNumber : 0
scriptId : <scriptId>
url :
}
]
}
text : Uncaught
}
Running test: testIntegerFormatter
Testing console.debug('%d', 42)...
debug[
[0] : {
type : string
value : %d
}
[1] : {
description : 42
type : number
value : 42
}
]
Testing console.error('%i', '987654321')...
error[
[0] : {
type : string
value : %i
}
[1] : {
description : 987654321
type : number
value : 987654321
}
]
Testing console.info('%d', Symbol('12345'))...
info[
[0] : {
type : string
value : %d
}
[1] : {
description : NaN
type : number
unserializableValue : NaN
}
]
Testing console.log('%i', {toString() { return '42'; }})...
log[
[0] : {
type : string
value : %i
}
[1] : {
description : 42
type : number
value : 42
}
]
Testing console.trace('%d', {[Symbol.toPrimitive]() { return 256; }})...
trace[
[0] : {
type : string
value : %d
}
[1] : {
description : 256
type : number
value : 256
}
]
Testing console.warn('%i', {toString() { throw new Error(); }})...
{
columnNumber : 33
exception : {
className : Error
description : Error at Object.toString (<anonymous>:1:40) at parseInt (<anonymous>) at console.warn (<anonymous>) at <anonymous>:1:9
objectId : <objectId>
subtype : error
type : object
}
exceptionId : <exceptionId>
lineNumber : 0
scriptId : <scriptId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 39
functionName : toString
lineNumber : 0
scriptId : <scriptId>
url :
}
[1] : {
columnNumber : 8
functionName :
lineNumber : 0
scriptId : <scriptId>
url :
}
]
}
text : Uncaught
}
Running test: testStringFormatter
Testing console.debug('%s', 42)...
debug[
[0] : {
type : string
value : %s
}
[1] : {
type : string
value : 42
}
]
Testing console.error('%s', 'Test string')...
error[
[0] : {
type : string
value : %s
}
[1] : {
type : string
value : Test string
}
]
Testing console.info('%s', Symbol('Test symbol'))...
info[
[0] : {
type : string
value : %s
}
[1] : {
type : string
value : Symbol(Test symbol)
}
]
Testing console.log('%s', {toString() { return 'Test object'; }})...
log[
[0] : {
type : string
value : %s
}
[1] : {
type : string
value : Test object
}
]
Testing console.trace('%s', {[Symbol.toPrimitive]() { return true; }})...
trace[
[0] : {
type : string
value : %s
}
[1] : {
type : string
value : true
}
]
Testing console.warn('%s', {toString() { throw new Error(); }})...
{
columnNumber : 33
exception : {
className : Error
description : Error at Object.toString (<anonymous>:1:40) at String (<anonymous>) at console.warn (<anonymous>) at <anonymous>:1:9
objectId : <objectId>
subtype : error
type : object
}
exceptionId : <exceptionId>
lineNumber : 0
scriptId : <scriptId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 39
functionName : toString
lineNumber : 0
scriptId : <scriptId>
url :
}
[1] : {
columnNumber : 8
functionName :
lineNumber : 0
scriptId : <scriptId>
url :
}
]
}
text : Uncaught
}
Running test: testOtherFormatters
Testing console.debug('%c', 'color:red')...
debug[
[0] : {
type : string
value : %c
}
[1] : {
type : string
value : color:red
}
]
Testing console.error('%o', {toString() { throw new Error(); }})...
error[
[0] : {
type : string
value : %o
}
[1] : {
className : Object
description : Object
objectId : 1.1.7
preview : {
description : Object
overflow : false
properties : [
[0] : {
name : toString
type : function
value :
}
]
type : object
}
type : object
}
]
Testing console.info('%O', {toString() { throw new Error(); }})...
info[
[0] : {
type : string
value : %O
}
[1] : {
className : Object
description : Object
objectId : 1.1.8
preview : {
description : Object
overflow : false
properties : [
[0] : {
name : toString
type : function
value :
}
]
type : object
}
type : object
}
]
Testing console.log('We have reached 100% of our users', 'with this!')...
log[
[0] : {
type : string
value : We have reached 100% of our users
}
[1] : {
type : string
value : with this!
}
]
Running test: testMultipleFormatters
Testing console.debug('%s%some Text%i', '', 'S', 1)...
debug[
[0] : {
type : string
value : %s%some Text%i
}
[1] : {
type : string
value :
}
[2] : {
type : string
value : S
}
[3] : {
description : 1
type : number
value : 1
}
]
Testing console.error('%c%i%c%s', 'color:red', 42, 'color:green', 'Message!')...
error[
[0] : {
type : string
value : %c%i%c%s
}
[1] : {
type : string
value : color:red
}
[2] : {
description : 42
type : number
value : 42
}
[3] : {
type : string
value : color:green
}
[4] : {
type : string
value : Message!
}
]
Testing console.info('%s', {toString() { return '%i% %s %s'; }}, {toString() { return '100'; }}, 'more', 'arguments')...
info[
[0] : {
type : string
value : %s
}
[1] : {
type : string
value : %i% %s %s
}
[2] : {
description : 100
type : number
value : 100
}
[3] : {
type : string
value : more
}
[4] : {
type : string
value : arguments
}
]
Testing console.log('%s %s', {toString() { return 'Too %s %s'; }}, 'many', 'specifiers')...
log[
[0] : {
type : string
value : %s %s
}
[1] : {
type : string
value : Too %s %s
}
[2] : {
type : string
value : many
}
[3] : {
type : string
value : specifiers
}
]
Testing console.trace('%s %f', {toString() { return '%s'; }}, {[Symbol.toPrimitive]() { return 'foo'; }}, 1, 'Test')...
trace[
[0] : {
type : string
value : %s %f
}
[1] : {
type : string
value : %s
}
[2] : {
type : string
value : foo
}
[3] : {
description : 1
type : number
value : 1
}
[4] : {
type : string
value : Test
}
]
Running test: testAssert
Testing console.assert(true, '%s', {toString() { throw new Error(); }})...
Testing console.assert(false, '%s %i', {toString() { return '%s'; }}, {[Symbol.toPrimitive]() { return 1; }}, 1, 'Test')...
assert[
[0] : {
type : string
value : %s %i
}
[1] : {
type : string
value : %s
}
[2] : {
type : string
value : 1
}
[3] : {
description : 1
type : number
value : 1
}
[4] : {
type : string
value : Test
}
]
Testing console.assert(false, '%s', {toString() { throw new Error(); }})...
{
columnNumber : 42
exception : {
className : Error
description : Error at Object.toString (<anonymous>:1:49) at String (<anonymous>) at console.assert (<anonymous>) at <anonymous>:1:9
objectId : <objectId>
subtype : error
type : object
}
exceptionId : <exceptionId>
lineNumber : 0
scriptId : <scriptId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 48
functionName : toString
lineNumber : 0
scriptId : <scriptId>
url :
}
[1] : {
columnNumber : 8
functionName :
lineNumber : 0
scriptId : <scriptId>
url :
}
]
}
text : Uncaught
}
Running test: testGroup
Testing console.group('%s', {toString() { throw new Error(); }})...
{
columnNumber : 34
exception : {
className : Error
description : Error at Object.toString (<anonymous>:1:41) at String (<anonymous>) at console.group (<anonymous>) at <anonymous>:1:9
objectId : <objectId>
subtype : error
type : object
}
exceptionId : <exceptionId>
lineNumber : 0
scriptId : <scriptId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 40
functionName : toString
lineNumber : 0
scriptId : <scriptId>
url :
}
[1] : {
columnNumber : 8
functionName :
lineNumber : 0
scriptId : <scriptId>
url :
}
]
}
text : Uncaught
}
Testing console.group('%s%i', 'Gruppe', {[Symbol.toPrimitive]() { return 1; }})...
startGroup[
[0] : {
type : string
value : %s%i
}
[1] : {
type : string
value : Gruppe
}
[2] : {
description : 1
type : number
value : 1
}
]
Testing console.groupEnd()...
endGroup[
[0] : {
type : string
value : console.groupEnd
}
]
Running test: testGroupCollapsed
Testing console.groupCollapsed('%d', {toString() { throw new Error(); }})...
{
columnNumber : 43
exception : {
className : Error
description : Error at Object.toString (<anonymous>:1:50) at parseInt (<anonymous>) at console.groupCollapsed (<anonymous>) at <anonymous>:1:9
objectId : <objectId>
subtype : error
type : object
}
exceptionId : <exceptionId>
lineNumber : 0
scriptId : <scriptId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 49
functionName : toString
lineNumber : 0
scriptId : <scriptId>
url :
}
[1] : {
columnNumber : 8
functionName :
lineNumber : 0
scriptId : <scriptId>
url :
}
]
}
text : Uncaught
}
Testing console.groupCollapsed('%s%f', {[Symbol.toPrimitive]() { return 'Gruppe'; }}, 3.1415)...
startGroupCollapsed[
[0] : {
type : string
value : %s%f
}
[1] : {
type : string
value : Gruppe
}
[2] : {
description : 3.1415
type : number
value : 3.1415
}
]
Testing console.groupEnd()...
endGroup[
[0] : {
type : string
value : console.groupEnd
}
]
Running test: testNonStandardFormatSpecifiers
Testing console.log('%_ %s', {toString() { throw new Error(); }}, {toString() { return 'foo'; }})...
log[
[0] : {
type : string
value : %_ %s
}
[1] : {
className : Object
description : Object
objectId : 1.1.15
preview : {
description : Object
overflow : false
properties : [
[0] : {
name : toString
type : function
value :
}
]
type : object
}
type : object
}
[2] : {
type : string
value : foo
}
]
Testing console.log('%%s', {toString() { throw new Error(); }})...
log[
[0] : {
type : string
value : %%s
}
[1] : {
className : Object
description : Object
objectId : 1.1.16
preview : {
description : Object
overflow : false
properties : [
[0] : {
name : toString
type : function
value :
}
]
type : object
}
type : object
}
]

View File

@ -0,0 +1,144 @@
// Copyright 2021 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
const {session, contextGroup, Protocol} =
InspectorTest.start('Test for console formatting');
Protocol.Runtime.onConsoleAPICalled(({params: {args, type}}) => {
InspectorTest.logObject(args, type);
});
async function test(expression) {
InspectorTest.logMessage(`Testing ${expression}...`);
const {result} = await Protocol.Runtime.evaluate({expression});
if ('exceptionDetails' in result) {
InspectorTest.logMessage(result.exceptionDetails);
}
}
InspectorTest.runAsyncTestSuite([
async function testFloatFormatter() {
await Protocol.Runtime.enable();
await test(`console.debug('%f', 3.1415)`);
await test(`console.error('%f', '3e2')`);
await test(`console.info('%f', Symbol('1.1'))`);
await test(`console.log('%f', {toString() { return '42'; }})`);
await test(
`console.trace('%f', {[Symbol.toPrimitive]() { return 2.78; }})`);
await test(`console.warn('%f', {toString() { throw new Error(); }})`);
await Promise.all([
Protocol.Runtime.discardConsoleEntries(),
Protocol.Runtime.disable(),
]);
},
async function testIntegerFormatter() {
await Protocol.Runtime.enable();
await test(`console.debug('%d', 42)`);
await test(`console.error('%i', '987654321')`);
await test(`console.info('%d', Symbol('12345'))`);
await test(`console.log('%i', {toString() { return '42'; }})`);
await test(`console.trace('%d', {[Symbol.toPrimitive]() { return 256; }})`);
await test(`console.warn('%i', {toString() { throw new Error(); }})`);
await Promise.all([
Protocol.Runtime.discardConsoleEntries(),
Protocol.Runtime.disable(),
]);
},
async function testStringFormatter() {
await Protocol.Runtime.enable();
await test(`console.debug('%s', 42)`);
await test(`console.error('%s', 'Test string')`);
await test(`console.info('%s', Symbol('Test symbol'))`);
await test(`console.log('%s', {toString() { return 'Test object'; }})`);
await test(
`console.trace('%s', {[Symbol.toPrimitive]() { return true; }})`);
await test(`console.warn('%s', {toString() { throw new Error(); }})`);
await Promise.all([
Protocol.Runtime.discardConsoleEntries(),
Protocol.Runtime.disable(),
]);
},
async function testOtherFormatters() {
await Protocol.Runtime.enable();
await test(`console.debug('%c', 'color:red')`);
await test(`console.error('%o', {toString() { throw new Error(); }})`);
await test(`console.info('%O', {toString() { throw new Error(); }})`);
await test(
`console.log('We have reached 100% of our users', 'with this!')`);
await Promise.all([
Protocol.Runtime.discardConsoleEntries(),
Protocol.Runtime.disable(),
]);
},
async function testMultipleFormatters() {
await Protocol.Runtime.enable();
await test(`console.debug('%s%some Text%i', '', 'S', 1)`);
await test(
`console.error('%c%i%c%s', 'color:red', 42, 'color:green', 'Message!')`);
await test(
`console.info('%s', {toString() { return '%i% %s %s'; }}, {toString() { return '100'; }}, 'more', 'arguments')`);
await test(
`console.log('%s %s', {toString() { return 'Too %s %s'; }}, 'many', 'specifiers')`);
await test(
`console.trace('%s %f', {toString() { return '%s'; }}, {[Symbol.toPrimitive]() { return 'foo'; }}, 1, 'Test')`);
await Promise.all([
Protocol.Runtime.discardConsoleEntries(),
Protocol.Runtime.disable(),
]);
},
async function testAssert() {
await Protocol.Runtime.enable();
await test(
`console.assert(true, '%s', {toString() { throw new Error(); }})`);
await test(
`console.assert(false, '%s %i', {toString() { return '%s'; }}, {[Symbol.toPrimitive]() { return 1; }}, 1, 'Test')`);
await test(
`console.assert(false, '%s', {toString() { throw new Error(); }})`);
await Promise.all([
Protocol.Runtime.discardConsoleEntries(),
Protocol.Runtime.disable(),
]);
},
async function testGroup() {
await Protocol.Runtime.enable();
await test(`console.group('%s', {toString() { throw new Error(); }})`);
await test(
`console.group('%s%i', 'Gruppe', {[Symbol.toPrimitive]() { return 1; }})`);
await test(`console.groupEnd()`);
await Promise.all([
Protocol.Runtime.discardConsoleEntries(),
Protocol.Runtime.disable(),
]);
},
async function testGroupCollapsed() {
await Protocol.Runtime.enable();
await test(
`console.groupCollapsed('%d', {toString() { throw new Error(); }})`);
await test(
`console.groupCollapsed('%s%f', {[Symbol.toPrimitive]() { return 'Gruppe'; }}, 3.1415)`);
await test(`console.groupEnd()`);
await Promise.all([
Protocol.Runtime.discardConsoleEntries(),
Protocol.Runtime.disable(),
]);
},
async function testNonStandardFormatSpecifiers() {
await Protocol.Runtime.enable();
await test(
`console.log('%_ %s', {toString() { throw new Error(); }}, {toString() { return 'foo'; }})`);
await test(`console.log('%%s', {toString() { throw new Error(); }})`);
await Promise.all([
Protocol.Runtime.discardConsoleEntries(),
Protocol.Runtime.disable(),
]);
}
]);

View File

@ -0,0 +1,53 @@
Tests line and column numbers in console messages
{
method : Runtime.consoleAPICalled
params : {
args : [
[0] : {
description : 239
type : number
value : 239
}
]
executionContextId : <executionContextId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 8
functionName :
lineNumber : 0
scriptId : <scriptId>
url :
}
]
}
timestamp : <timestamp>
type : log
}
}
{
method : Runtime.consoleAPICalled
params : {
args : [
[0] : {
description : 239
type : number
value : 239
}
]
executionContextId : <executionContextId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 2
functionName :
lineNumber : 1
scriptId : <scriptId>
url :
}
]
}
timestamp : <timestamp>
type : log
}
}

View File

@ -0,0 +1,20 @@
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
let {session, contextGroup, Protocol} = InspectorTest.start('Tests line and column numbers in console messages');
Protocol.Runtime.enable();
addConsoleMessagePromise("console.log(239)")
.then(message => InspectorTest.logMessage(message))
.then(() => addConsoleMessagePromise("var l = console.log;\n l(239)"))
.then(message => InspectorTest.logMessage(message))
.then(() => InspectorTest.completeTest());
function addConsoleMessagePromise(expression)
{
var wait = Protocol.Runtime.onceConsoleAPICalled();
Protocol.Runtime.evaluate({ expression: expression });
return wait;
}

View File

@ -0,0 +1,20 @@
Check that console.log doesn't run microtasks.
{
description : 42
type : number
value : 42
}
{
description : 43
type : number
value : 43
}
{
description : 239
type : number
value : 239
}
{
type : string
value : finished
}

View File

@ -0,0 +1,26 @@
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
let {session, contextGroup, Protocol} = InspectorTest.start("Check that console.log doesn't run microtasks.");
contextGroup.addScript(
`
function testFunction()
{
Promise.resolve().then(function(){ console.log(239); });
console.log(42);
console.log(43);
}`);
Protocol.Runtime.enable();
Protocol.Runtime.onConsoleAPICalled(messageAdded);
Protocol.Runtime.evaluate({ "expression": "testFunction()" });
Protocol.Runtime.evaluate({ "expression": "setTimeout(() => console.log(\"finished\"), 0)" });
function messageAdded(result)
{
InspectorTest.logObject(result.params.args[0]);
if (result.params.args[0].value === "finished")
InspectorTest.completeTest();
}

View File

@ -0,0 +1,45 @@
Checks console.memory
Running test: testWithoutMemory
{
id : <messageId>
result : {
result : {
type : undefined
}
}
}
Running test: testSetterInStrictMode
{
id : <messageId>
result : {
result : {
type : undefined
}
}
}
Running test: testWithMemory
{
id : <messageId>
result : {
result : {
description : 239
type : number
value : 239
}
}
}
Running test: testSetterDoesntOverride
{
id : <messageId>
result : {
result : {
description : 42
type : number
value : 42
}
}
}

View File

@ -0,0 +1,32 @@
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
let {session, contextGroup, Protocol} = InspectorTest.start('Checks console.memory');
InspectorTest.runAsyncTestSuite([
async function testWithoutMemory() {
InspectorTest.logMessage(
await Protocol.Runtime.evaluate({expression: 'console.memory'}));
},
async function testSetterInStrictMode() {
// crbug.com/468611
InspectorTest.logMessage(
await Protocol.Runtime.evaluate({
expression: '"use strict"\nconsole.memory = {};undefined' }));
},
async function testWithMemory() {
utils.setMemoryInfoForTest(239);
InspectorTest.logMessage(
await Protocol.Runtime.evaluate({expression: 'console.memory'}));
},
async function testSetterDoesntOverride() {
utils.setMemoryInfoForTest(42);
await Protocol.Runtime.evaluate({expression: 'console.memory = 0'});
InspectorTest.logMessage(
await Protocol.Runtime.evaluate({expression: 'console.memory'}));
}
]);

View File

@ -0,0 +1,100 @@
Checks that console messages before Runtime.enable include a single stack frame
Running test: testEnable
{
args : [
[0] : {
type : string
value : Error on toplevel
}
]
executionContextId : <executionContextId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 8
functionName :
lineNumber : 10
scriptId : <scriptId>
url : test.js
}
]
}
timestamp : <timestamp>
type : error
}
{
args : [
[0] : {
type : string
value : Hello from foo!
}
]
executionContextId : <executionContextId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 10
functionName : foo
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
]
}
timestamp : <timestamp>
type : log
}
{
args : [
[0] : {
type : string
value : Hello from bar!
}
]
executionContextId : <executionContextId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 10
functionName : bar
lineNumber : 6
scriptId : <scriptId>
url : test.js
}
[1] : {
columnNumber : 0
functionName :
lineNumber : 12
scriptId : <scriptId>
url : test.js
}
]
}
timestamp : <timestamp>
type : trace
}
{
args : [
[0] : {
type : string
value : Hello from foo!
}
]
executionContextId : <executionContextId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 10
functionName : foo
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
]
}
timestamp : <timestamp>
type : log
}
Running test: testEnableAfterDiscard

View File

@ -0,0 +1,37 @@
// Copyright 2022 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
const {session, contextGroup, Protocol} = InspectorTest.start(
'Checks that console messages before Runtime.enable include a single stack frame');
contextGroup.addScript(`
function foo() {
console.log("Hello from foo!");
}
function bar() {
console.trace("Hello from bar!");
foo();
}
console.error('Error on toplevel');
foo();
bar();
//# sourceURL=test.js`);
Protocol.Runtime.onConsoleAPICalled(
({params}) => InspectorTest.logMessage(params));
InspectorTest.runAsyncTestSuite([
async function testEnable() {
await Protocol.Runtime.enable();
await Protocol.Runtime.disable();
},
async function testEnableAfterDiscard() {
await Protocol.Runtime.discardConsoleEntries();
await Protocol.Runtime.enable();
await Protocol.Runtime.disable();
}
]);

View File

@ -0,0 +1,6 @@
Checks that we only send along non-data urls.
Test log with data uri.
console api called: Hello World!
callFrame: function test (url: )
callFrame: function (url: test.js)
exception details: Uncaught ReferenceError: Exception is not defined (url: )

View File

@ -0,0 +1,63 @@
// Copyright 2021 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
let {session, contextGroup, Protocol} = InspectorTest.start('Checks that we only send along non-data urls.');
var expectedMessages = 2;
var messages = [];
Protocol.Runtime.enable();
Protocol.Console.enable();
Protocol.Runtime.onConsoleAPICalled(consoleAPICalled);
Protocol.Runtime.onExceptionThrown(exceptionThrown);
contextGroup.addScript(`
async function test() {
console.log("Hello World!");
throw new Exception("Exception thrown");
}
//# sourceURL=data:,pseudoDataUrl`);
function consoleAPICalled(result)
{
const msgText = result.params.args[0].value;
const callFrames = result.params.stackTrace.callFrames;
let messageParts = [];
messageParts.push(`console api called: ${msgText}`);
for (frame of callFrames) {
messageParts.push(` callFrame: function ${frame.functionName} (url: ${frame.url})`);
}
messages.push(messageParts.join("\n"));
if (!(--expectedMessages)) {
done();
}
}
function exceptionThrown(result)
{
const exceptionDetails = result.params.exceptionDetails;
const url = exceptionDetails.url;
const text = exceptionDetails.text;
messages.push(`exception details: ${text} (url: ${url ? url : ""})`)
if (!(--expectedMessages)) {
done();
}
}
function done()
{
messages.sort();
for (var message of messages) {
InspectorTest.log(message);
}
InspectorTest.completeTest();
}
(async function test() {
InspectorTest.log('Test log with data uri.');
await Protocol.Runtime.evaluate({ expression: `test()//# sourceURL=test.js`});
})();

View File

@ -0,0 +1,7 @@
Checks that console message storage doesn't exceed limits
Running test: testMaxConsoleMessagesCount
Messages reported: 1000
Running test: testMaxConsoleMessagesV8Size
Messages reported: 5

View File

@ -0,0 +1,44 @@
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
let {session, contextGroup, Protocol} = InspectorTest.start('Checks that console message storage doesn\'t exceed limits');
contextGroup.addScript(`
function generateEmptyMessages(n) {
for (var i = 0; i < n; ++i) {
console.log('');
}
}
function generate1MbMessages(n) {
for (var i = 0; i < n; ++i) {
console.log(new Array(1024 * 1024 - 32).join('!'));
}
}
//# sourceURL=test.js`, 7, 26);
var messagesReported = 0;
Protocol.Runtime.onConsoleAPICalled(message => {
++messagesReported;
});
InspectorTest.runTestSuite([
function testMaxConsoleMessagesCount(next) {
messagesReported = 0;
Protocol.Runtime.evaluate({ expression: 'generateEmptyMessages(1005)'})
.then(() => Protocol.Runtime.enable())
.then(() => Protocol.Runtime.disable())
.then(() => InspectorTest.log(`Messages reported: ${messagesReported}`))
.then(next);
},
function testMaxConsoleMessagesV8Size(next) {
messagesReported = 0;
Protocol.Runtime.evaluate({ expression: 'generate1MbMessages(11)'})
.then(() => Protocol.Runtime.enable())
.then(() => Protocol.Runtime.disable())
.then(() => InspectorTest.log(`Messages reported: ${messagesReported}`))
.then(next);
}
]);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,53 @@
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
let {session, contextGroup, Protocol} = InspectorTest.start('Checks console methods');
contextGroup.setupInjectedScriptEnvironment();
contextGroup.addScript(`
function testFunction() {
console.debug('debug');
console.error('error');
console.info('info');
console.log('log');
console.warn('warn');
console.dir('dir');
console.dirxml('dirxml');
console.table([[1,2],[3,4]]);
console.table([[1,2],[3,4]], ['1','2']);
console.trace('trace');
console.trace();
console.group();
console.groupEnd();
console.groupCollapsed();
console.clear('clear');
console.clear();
console.count('count');
function foo() {
console.count();
}
foo();
foo();
console.count();
console.count(undefined);
console.count('default');
console.countReset();
console.count();
console.countReset(undefined);
console.count();
console.countReset('default');
console.count();
console.countReset('countReset');
console.table('foo');
console.table(2);
console.table(2n);
console.table(Symbol('foo'));
console.table(function() {});
}
//# sourceURL=test.js`, 7, 26);
Protocol.Runtime.onConsoleAPICalled(InspectorTest.logMessage);
Protocol.Runtime.enable();
Protocol.Runtime.evaluate({ expression: 'testFunction()' })
.then(InspectorTest.completeTest);

View File

@ -0,0 +1,30 @@
Tests console object and it's prototype
Running test: consoleExistsOnGlobal
true
Running test: consoleHasRightPropertyDescriptor
{
configurable : true
enumerable : false
value : <value>
writable : true
}
Running test: ConsoleNotExistsOnGlobal
false
Running test: prototypeChainMustBeCorrect
true
Running test: consoleToString
[object console]
Running test: consoleMethodPropertyDescriptor
{
configurable : true
enumerable : true
value : {
}
writable : true
}

View File

@ -0,0 +1,60 @@
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
let {session, contextGroup, Protocol} = InspectorTest.start('Tests console object and it\'s prototype');
contextGroup.addScript(`
var self = this;
function checkPrototype() {
const prototype1 = Object.getPrototypeOf(console);
const prototype2 = Object.getPrototypeOf(prototype1);
if (Object.getOwnPropertyNames(prototype1).length !== 0)
return "false: The [[Prototype]] must have no properties";
if (prototype2 !== Object.prototype)
return "false: The [[Prototype]]'s [[Prototype]] must be %ObjectPrototype%";
return "true";
}
`);
InspectorTest.runAsyncTestSuite([
async function consoleExistsOnGlobal() {
let message = await Protocol.Runtime.evaluate({
expression: 'self.hasOwnProperty(\'console\')', returnByValue: true});
InspectorTest.log(message.result.result.value);
},
async function consoleHasRightPropertyDescriptor() {
let message = await Protocol.Runtime.evaluate({
expression: 'Object.getOwnPropertyDescriptor(self, \'console\')',
returnByValue: true});
let result = message.result.result.value;
result.value = '<value>';
InspectorTest.logObject(result);
},
async function ConsoleNotExistsOnGlobal() {
let message = await Protocol.Runtime.evaluate({
expression: '\'Console\' in self', returnByValue: true})
InspectorTest.log(message.result.result.value);
},
async function prototypeChainMustBeCorrect() {
let message = await Protocol.Runtime.evaluate({
expression: "checkPrototype()", returnByValue: true });
InspectorTest.log(message.result.result.value);
},
async function consoleToString() {
let message = await Protocol.Runtime.evaluate({
expression: 'console.toString()', returnByValue: true})
InspectorTest.log(message.result.result.value);
},
async function consoleMethodPropertyDescriptor() {
let message = await Protocol.Runtime.evaluate({
expression: 'Object.getOwnPropertyDescriptor(console, \'log\')',
returnByValue: true});
InspectorTest.logObject(message.result.result.value);
}
]);

View File

@ -0,0 +1,479 @@
console.table
{
description : Array(3)
overflow : false
properties : [
[0] : {
name : 0
type : string
value : apples
}
[1] : {
name : 1
type : string
value : oranges
}
[2] : {
name : 2
type : string
value : bananas
}
]
subtype : array
type : object
}
{
description : Person
overflow : false
properties : [
[0] : {
name : firstName
type : string
value : John
}
[1] : {
name : lastName
type : string
value : Smith
}
]
type : object
}
{
description : Array(3)
overflow : false
properties : [
[0] : {
name : 0
subtype : array
type : object
value : Array(2)
valuePreview : {
description : Array(2)
overflow : false
properties : [
[0] : {
name : 0
type : string
value : John
}
[1] : {
name : 1
type : string
value : Smith
}
]
subtype : array
type : object
}
}
[1] : {
name : 1
subtype : array
type : object
value : Array(2)
valuePreview : {
description : Array(2)
overflow : false
properties : [
[0] : {
name : 0
type : string
value : Jane
}
[1] : {
name : 1
type : string
value : Doe
}
]
subtype : array
type : object
}
}
[2] : {
name : 2
subtype : array
type : object
value : Array(2)
valuePreview : {
description : Array(2)
overflow : false
properties : [
[0] : {
name : 0
type : string
value : Emily
}
[1] : {
name : 1
type : string
value : Jones
}
]
subtype : array
type : object
}
}
]
subtype : array
type : object
}
{
description : Array(3)
overflow : false
properties : [
[0] : {
name : 0
type : object
value : Person
valuePreview : {
description : Person
overflow : false
properties : [
[0] : {
name : firstName
type : string
value : John
}
[1] : {
name : lastName
type : string
value : Smith
}
]
type : object
}
}
[1] : {
name : 1
type : object
value : Person
valuePreview : {
description : Person
overflow : false
properties : [
[0] : {
name : firstName
type : string
value : Jane
}
[1] : {
name : lastName
type : string
value : Doe
}
]
type : object
}
}
[2] : {
name : 2
type : object
value : Person
valuePreview : {
description : Person
overflow : false
properties : [
[0] : {
name : firstName
type : string
value : Emily
}
[1] : {
name : lastName
type : string
value : Jones
}
]
type : object
}
}
]
subtype : array
type : object
}
{
description : Object
overflow : false
properties : [
[0] : {
name : mother
type : object
value : Person
valuePreview : {
description : Person
overflow : false
properties : [
[0] : {
name : firstName
type : string
value : Jane
}
[1] : {
name : lastName
type : string
value : Smith
}
]
type : object
}
}
[1] : {
name : father
type : object
value : Person
valuePreview : {
description : Person
overflow : false
properties : [
[0] : {
name : firstName
type : string
value : John
}
[1] : {
name : lastName
type : string
value : Smith
}
]
type : object
}
}
[2] : {
name : daughter
type : object
value : Person
valuePreview : {
description : Person
overflow : false
properties : [
[0] : {
name : firstName
type : string
value : Emily
}
[1] : {
name : lastName
type : string
value : Smith
}
]
type : object
}
}
]
type : object
}
{
description : Array(3)
overflow : false
properties : [
[0] : {
name : 0
type : object
value : Person
valuePreview : {
description : Person
overflow : false
properties : [
[0] : {
name : firstName
type : string
value : John
}
]
type : object
}
}
[1] : {
name : 1
type : object
value : Person
valuePreview : {
description : Person
overflow : false
properties : [
[0] : {
name : firstName
type : string
value : Jane
}
]
type : object
}
}
[2] : {
name : 2
type : object
value : Person
valuePreview : {
description : Person
overflow : false
properties : [
[0] : {
name : firstName
type : string
value : Emily
}
]
type : object
}
}
]
subtype : array
type : object
}
last value property:
{
name : 1
type : string
value : b
}
last property:
{
name : 998
subtype : array
type : object
value : Array(2)
valuePreview : {
description : Array(2)
overflow : false
properties : <ValuePreviewPropertiesArray(2)>
subtype : array
type : object
}
}
preview:
{
description : Array(999)
overflow : false
properties : <PropertiesArray(999)>
subtype : array
type : object
}
last value property:
{
name : 1
type : string
value : b
}
last property:
{
name : 999
subtype : array
type : object
value : Array(2)
valuePreview : {
description : Array(2)
overflow : false
properties : <ValuePreviewPropertiesArray(2)>
subtype : array
type : object
}
}
preview:
{
description : Array(1001)
overflow : true
properties : <PropertiesArray(1000)>
subtype : array
type : object
}
{
description : Array(2)
overflow : false
properties : [
[0] : {
name : 0
type : object
value : Object
valuePreview : {
description : Object
overflow : false
properties : [
[0] : {
name : c
type : number
value : 3
}
[1] : {
name : b
type : number
value : 2
}
]
type : object
}
}
[1] : {
name : 1
type : object
value : Object
valuePreview : {
description : Object
overflow : false
properties : [
[0] : {
name : c
type : number
value : 3
}
]
type : object
}
}
]
subtype : array
type : object
}
{
description : Array(2)
overflow : false
properties : [
[0] : {
name : 0
type : object
value : Object
valuePreview : {
description : Object
overflow : false
properties : [
[0] : {
name : c
type : number
value : 3
}
[1] : {
name : b
type : number
value : 2
}
]
type : object
}
}
[1] : {
name : 1
type : object
value : Object
valuePreview : {
description : Object
overflow : false
properties : [
[0] : {
name : c
type : number
value : 3
}
]
type : object
}
}
]
subtype : array
type : object
}

View File

@ -0,0 +1,114 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
const { session, contextGroup, Protocol } =
InspectorTest.start('console.table');
(async function test() {
Protocol.Runtime.enable();
Protocol.Runtime.evaluate({
expression: `console.table(['apples', 'oranges', 'bananas'])`
});
await waitConsoleAPICalledAndDump();
Protocol.Runtime.evaluate({
expression: `function Person(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
};
var me = new Person('John', 'Smith');
console.table(me);`
});
await waitConsoleAPICalledAndDump();
Protocol.Runtime.evaluate({
expression: `var people = [
['John', 'Smith'], ['Jane', 'Doe'], ['Emily', 'Jones']];
console.table(people);`
});
await waitConsoleAPICalledAndDump();
Protocol.Runtime.evaluate({
expression: `function Person(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
var john = new Person('John', 'Smith');
var jane = new Person('Jane', 'Doe');
var emily = new Person('Emily', 'Jones');
console.table([john, jane, emily]);`
});
await waitConsoleAPICalledAndDump();
Protocol.Runtime.evaluate({
expression: `var family = {};
family.mother = new Person('Jane', 'Smith');
family.father = new Person('John', 'Smith');
family.daughter = new Person('Emily', 'Smith');
console.table(family);`
});
await waitConsoleAPICalledAndDump();
Protocol.Runtime.evaluate({
expression: `console.table([john, jane, emily], ['firstName'])`
});
await waitConsoleAPICalledAndDump();
Protocol.Runtime.evaluate({
expression: `var bigTable = new Array(999);
bigTable.fill(['a', 'b']);
console.table(bigTable);`
});
await waitConsoleAPICalledAndDump(true /* concise */);
Protocol.Runtime.evaluate({
expression: `var bigTable = new Array(1001);
bigTable.fill(['a', 'b']);
console.table(bigTable);`
});
await waitConsoleAPICalledAndDump(true /* concise */);
Protocol.Runtime.evaluate({
expression: `var table = [{a:1, b:2, c:3}, {c:3}];
var filter = ['c', 'b'];
console.table(table, filter);`
});
await waitConsoleAPICalledAndDump();
Protocol.Runtime.evaluate({
expression: `var table = [{a:1, b:2, c:3}, {c:3}];
var filter = ['c', 'b', 'c'];
console.table(table, filter);`
});
await waitConsoleAPICalledAndDump();
InspectorTest.completeTest();
})()
/**
* @param {boolean=} concise
*/
async function waitConsoleAPICalledAndDump(concise) {
const { params : {
args: [ arg ]
} } = await Protocol.Runtime.onceConsoleAPICalled();
const preview = arg.preview;
if (concise)
simplifyAndPrintLast(preview);
else
InspectorTest.logMessage(arg.preview);
function simplifyAndPrintLast(preview) {
if (!Array.isArray(preview.properties))
return;
const properties = preview.properties;
const lastProperty = properties[properties.length - 1];
if (lastProperty.valuePreview && lastProperty.valuePreview.properties) {
const innerProperties = lastProperty.valuePreview.properties;
InspectorTest.logMessage(`last value property:`);
InspectorTest.logMessage(innerProperties[innerProperties.length - 1]);
lastProperty.valuePreview.properties = `<ValuePreviewPropertiesArray(${innerProperties.length})>`;
}
InspectorTest.logMessage(`last property:`);
InspectorTest.logMessage(lastProperty);
preview.properties = `<PropertiesArray(${properties.length})>`;
InspectorTest.logMessage(`preview:`);
InspectorTest.logMessage(preview);
InspectorTest.logMessage(``);
}
}

View File

@ -0,0 +1,29 @@
Test for default label with console.time() and friends
[
[0] : {
type : string
value : default: 1 ms
}
[1] : {
type : string
value : a
}
]
[
[0] : {
type : string
value : default: 2 ms
}
]
[
[0] : {
type : string
value : default: 1 ms
}
]
[
[0] : {
type : string
value : default: 2 ms
}
]

View File

@ -0,0 +1,43 @@
// Copyright 2024 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
const {session, contextGroup, Protocol} = InspectorTest.start(
'Test for default label with console.time() and friends');
(async function test() {
await Protocol.Runtime.enable();
utils.setCurrentTimeMSForTest(0.0);
await Protocol.Runtime.evaluate({expression: `console.time(undefined)`});
utils.setCurrentTimeMSForTest(1.0);
await Promise.all([
Protocol.Runtime.evaluate({expression: `console.timeLog(undefined, 'a')`}),
Protocol.Runtime.onceConsoleAPICalled().then(logArgs),
]);
utils.setCurrentTimeMSForTest(2.0);
await Promise.all([
Protocol.Runtime.evaluate({expression: `console.timeEnd(undefined)`}),
Protocol.Runtime.onceConsoleAPICalled().then(logArgs),
]);
utils.setCurrentTimeMSForTest(3.0);
await Protocol.Runtime.evaluate({expression: `console.time()`});
utils.setCurrentTimeMSForTest(4.0);
await Promise.all([
Protocol.Runtime.evaluate({expression: `console.timeLog()`}),
Protocol.Runtime.onceConsoleAPICalled().then(logArgs),
]);
utils.setCurrentTimeMSForTest(5.0);
await Promise.all([
Protocol.Runtime.evaluate({expression: `console.timeEnd()`}),
Protocol.Runtime.onceConsoleAPICalled().then(logArgs),
]);
await Protocol.Runtime.disable();
InspectorTest.completeTest();
})()
function logArgs(message) {
InspectorTest.logMessage(message.params.args);
}

View File

@ -0,0 +1,37 @@
Checks format of console.timeEnd output
Running test: zero
js: 0 ms
timeEnd: 0 ms
Running test: verySmall
js: 1e-15 ms
timeEnd: 1e-15 ms
Running test: small
js: 0.001 ms
timeEnd: 0.001 ms
Running test: regular
js: 1.2345 ms
timeEnd: 1.2345 ms
Running test: big
js: 10000.2345 ms
timeEnd: 10000.2345 ms
Running test: veryBig
js: 1000000000000000.2 ms
timeEnd: 1000000000000000.2 ms
Running test: huge
js: 1e+42 ms
timeEnd: 1e+42 ms
Running test: undefinedAsLabel
js: 1 ms
default: 1 ms
Running test: emptyAsLabel
js: 1 ms
default: 1 ms

View File

@ -0,0 +1,51 @@
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
let {session, contextGroup, Protocol} = InspectorTest.start('Checks format of console.timeEnd output');
Protocol.Runtime.enable();
Protocol.Runtime.onConsoleAPICalled(message => {
InspectorTest.log(message.params.args[0].value);
});
InspectorTest.runAsyncTestSuite([
function zero() {
return checkInterval(0.0);
},
function verySmall() {
return checkInterval(1e-15);
},
function small() {
return checkInterval(0.001);
},
function regular() {
return checkInterval(1.2345);
},
function big() {
return checkInterval(10000.2345);
},
function veryBig() {
return checkInterval(1e+15 + 0.2345);
},
function huge() {
return checkInterval(1e+42);
},
function undefinedAsLabel() {
return checkInterval(1.0, 'undefined');
},
function emptyAsLabel() {
return checkInterval(1.0, '');
}
]);
async function checkInterval(time, label) {
label = label === undefined ? '\'timeEnd\'' : label;
utils.setCurrentTimeMSForTest(0.0);
Protocol.Runtime.evaluate({
expression: `console.log('js: ' + ${time} + ' ms')`
});
await Protocol.Runtime.evaluate({expression: `console.time(${label})`});
utils.setCurrentTimeMSForTest(time);
await Protocol.Runtime.evaluate({expression: `console.timeEnd(${label})`});
}

View File

@ -0,0 +1,7 @@
Checks that console.timeEnd() always attached exactly one stack frame
Running test: top
Stack depth: 1
Running test: deep
Stack depth: 1

View File

@ -0,0 +1,37 @@
// Copyright 2024 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
let {session, contextGroup, Protocol} = InspectorTest.start(
'Checks that console.timeEnd() always attached exactly one stack frame');
Protocol.Runtime.enable();
InspectorTest.runAsyncTestSuite([
function top() {
return checkStack(1);
},
function deep() {
return checkStack(100);
},
]);
async function checkStack(depth) {
await Promise.all([
Protocol.Runtime.onceConsoleAPICalled().then(({params}) => {
InspectorTest.log('Stack depth: ' + params.stackTrace.callFrames.length);
}),
Protocol.Runtime.evaluate({
expression: `
console.time('foo'),
(function recurse(depth) {
if (depth <= 1) {
console.timeEnd('foo');
} else {
recurse(depth - 1);
}
})(${depth})
`
}),
]);
}

View File

@ -0,0 +1,37 @@
Test for console.timeLog
[
[0] : {
type : string
value : 42: 1 ms
}
[1] : {
type : string
value : a
}
]
[
[0] : {
type : string
value : 42: 2 ms
}
[1] : {
type : string
value : a
}
[2] : {
type : string
value : b
}
]
[
[0] : {
type : string
value : 42: 3 ms
}
]
[
[0] : {
type : string
value : Timer '42' does not exist
}
]

View File

@ -0,0 +1,29 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
const {session, contextGroup, Protocol} =
InspectorTest.start('Test for console.timeLog');
(async function test() {
Protocol.Runtime.enable();
utils.setCurrentTimeMSForTest(0.0);
await Protocol.Runtime.evaluate({expression: `console.time('42')`});
utils.setCurrentTimeMSForTest(1.0);
Protocol.Runtime.evaluate({expression: `console.timeLog('42', 'a')`});
logArgs(await Protocol.Runtime.onceConsoleAPICalled());
utils.setCurrentTimeMSForTest(2.0);
Protocol.Runtime.evaluate({expression: `console.timeLog('42', 'a', 'b')`});
logArgs(await Protocol.Runtime.onceConsoleAPICalled());
utils.setCurrentTimeMSForTest(3.0);
Protocol.Runtime.evaluate({expression: `console.timeEnd('42')`});
logArgs(await Protocol.Runtime.onceConsoleAPICalled());
utils.setCurrentTimeMSForTest(4.0);
Protocol.Runtime.evaluate({expression: `console.timeLog('42', 'text')`});
logArgs(await Protocol.Runtime.onceConsoleAPICalled());
InspectorTest.completeTest();
})()
function logArgs(message) {
InspectorTest.logMessage(message.params.args);
}

View File

@ -0,0 +1,76 @@
Checks that repeated console.time do not reset
{
method : Runtime.consoleAPICalled
params : {
args : [
[0] : {
type : string
value : Timer 'a' already exists
}
]
executionContextId : <executionContextId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 8
functionName :
lineNumber : 0
scriptId : <scriptId>
url :
}
]
}
timestamp : <timestamp>
type : warning
}
}
{
method : Runtime.consoleAPICalled
params : {
args : [
[0] : {
type : string
value : a: 2 ms
}
]
executionContextId : <executionContextId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 8
functionName :
lineNumber : 0
scriptId : <scriptId>
url :
}
]
}
timestamp : <timestamp>
type : timeEnd
}
}
{
method : Runtime.consoleAPICalled
params : {
args : [
[0] : {
type : string
value : Timer 'a' does not exist
}
]
executionContextId : <executionContextId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 8
functionName :
lineNumber : 0
scriptId : <scriptId>
url :
}
]
}
timestamp : <timestamp>
type : warning
}
}

View File

@ -0,0 +1,20 @@
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
let {session, contextGroup, Protocol} = InspectorTest.start('Checks that repeated console.time do not reset');
Protocol.Runtime.onConsoleAPICalled(InspectorTest.logMessage);
Protocol.Runtime.enable();
(async function() {
utils.setCurrentTimeMSForTest(0.0);
await Protocol.Runtime.evaluate({expression: `console.time('a')`});
utils.setCurrentTimeMSForTest(1.0);
await Protocol.Runtime.evaluate({expression: `console.time('a')`});
utils.setCurrentTimeMSForTest(2.0);
await Protocol.Runtime.evaluate({expression: `console.timeEnd('a')`});
utils.setCurrentTimeMSForTest(5.0);
await Protocol.Runtime.evaluate({expression: `console.timeEnd('a')`});
InspectorTest.completeTest();
})();

View File

@ -0,0 +1,9 @@
Tests timestamps in console
Message has timestamp: true
Message timestamp doesn't differ too much from current time (one minute interval): true
Message 1 has non-decreasing timestamp: true
Message has timestamp: true
Message timestamp doesn't differ too much from current time (one minute interval): true
Message 2 has non-decreasing timestamp: true
Message has timestamp: true
Message timestamp doesn't differ too much from current time (one minute interval): true

View File

@ -0,0 +1,25 @@
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
let {session, contextGroup, Protocol} = InspectorTest.start('Tests timestamps in console');
var messages = [];
function messageAdded(data)
{
var payload = data.params;
if (messages.length > 0)
InspectorTest.log("Message " + messages.length + " has non-decreasing timestamp: " + (payload.timestamp >= messages[messages.length - 1].timestamp));
messages.push(payload);
InspectorTest.log("Message has timestamp: " + !!payload.timestamp);
InspectorTest.log("Message timestamp doesn't differ too much from current time (one minute interval): " + (Math.abs(new Date().getTime() - payload.timestamp) < 60000));
if (messages.length === 3)
InspectorTest.completeTest();
}
Protocol.Runtime.onConsoleAPICalled(messageAdded);
Protocol.Runtime.enable();
Protocol.Runtime.evaluate({ expression: "console.log('testUnique'); for (var i = 0; i < 2; ++i) console.log('testDouble');" });

View File

@ -0,0 +1,8 @@
Tests that contextDesrtoyed nofitication is fired when context is collected.
{
method : Runtime.executionContextDestroyed
params : {
executionContextId : <executionContextId>
executionContextUniqueId : <executionContextUniqueId>
}
}

View File

@ -0,0 +1,16 @@
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --no-stress-incremental-marking
let {session, contextGroup, Protocol} =
InspectorTest.start('Tests that contextDesrtoyed nofitication is fired when context is collected.');
(async function test() {
await Protocol.Runtime.enable();
Protocol.Runtime.onExecutionContextDestroyed(InspectorTest.logMessage);
contextGroup.addScript('inspector.freeContext()');
await Protocol.HeapProfiler.collectGarbage();
InspectorTest.completeTest();
})();

View File

@ -0,0 +1,61 @@
Checks createContext().
{
method : Runtime.executionContextCreated
params : {
context : {
id : 1
name :
origin :
uniqueId : <uniqueId>
}
}
}
{
method : Runtime.executionContextCreated
params : {
context : {
id : 2
name :
origin :
uniqueId : <uniqueId>
}
}
}
{
id : <messageId>
result : {
debuggerId : <debuggerId>
}
}
#debugger;
setTimeout(x => x #* 3, 0)
Reported script's execution id: 2
{
method : Runtime.executionContextCreated
params : {
context : {
id : 1
name :
origin :
uniqueId : <uniqueId>
}
}
}
{
method : Runtime.executionContextCreated
params : {
context : {
id : 2
name :
origin :
uniqueId : <uniqueId>
}
}
}
#debugger;
setTimeout(x => x #* 3, 0)
Reported script's execution id: 2

View File

@ -0,0 +1,51 @@
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
InspectorTest.log('Checks createContext().');
var executionContextIds = new Set();
var contextGroup1 = new InspectorTest.ContextGroup();
var session1 = contextGroup1.connect();
setup(session1);
var contextGroup2 = new InspectorTest.ContextGroup();
var session2 = contextGroup2.connect();
setup(session2);
session1.Protocol.Runtime.enable()
.then(() => session2.Protocol.Runtime.enable({}))
.then(() => session1.Protocol.Debugger.enable())
.then(() => session2.Protocol.Debugger.enable({}))
.then(InspectorTest.logMessage)
.then(() => {
session1.Protocol.Runtime.evaluate({ expression: 'debugger;' });
session2.Protocol.Runtime.evaluate({expression: 'setTimeout(x => x * 2, 0)'});
session1.Protocol.Runtime.evaluate({ expression: 'setTimeout(x => x * 3, 0)' });
})
.then(() => InspectorTest.waitForPendingTasks())
.then(() => {
InspectorTest.log(`Reported script's execution id: ${executionContextIds.size}`);
executionContextIds.clear();
})
.then(() => session1.reconnect())
.then(() => session2.reconnect())
.then(() => {
session1.Protocol.Runtime.evaluate({ expression: 'debugger;' })
session2.Protocol.Runtime.evaluate({ expression: 'setTimeout(x => x * 2, 0)' });
session1.Protocol.Runtime.evaluate({ expression: 'setTimeout(x => x * 3, 0)' });
})
.then(() => InspectorTest.waitForPendingTasks())
.then(() => session2.Protocol.Debugger.disable({}))
.then(() => session1.Protocol.Debugger.disable({}))
.then(() => InspectorTest.log(`Reported script's execution id: ${executionContextIds.size}`))
.then(InspectorTest.completeTest);
function setup(session) {
session.Protocol.Runtime.onExecutionContextCreated(InspectorTest.logMessage);
session.setupScriptMap();
session.Protocol.Debugger.onPaused((message) => {
session.logSourceLocation(message.params.callFrames[0].location);
session.Protocol.Debugger.stepOut();
});
session.Protocol.Debugger.onScriptParsed(message => executionContextIds.add(message.params.executionContextId));
}

View File

@ -0,0 +1,97 @@
Checks that error.stack works correctly for custom Error subclasses
{
className : MyError
description : MyError: custom message at <anonymous>:1:18 at recurse (test.js:4:10) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at foo (test.js:8:3) at <anonymous>:1:1
objectId : <objectId>
subtype : error
type : object
}
{
className : MyError
description : MyError: foo at <anonymous>:1:18 at recurse (test.js:4:10) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at foo (test.js:8:3) at <anonymous>:1:1
objectId : <objectId>
subtype : error
type : object
}
{
className : ErrorWithCustomName
description : NamedError: bar at <anonymous>:1:18 at recurse (test.js:4:10) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at foo (test.js:8:3) at <anonymous>:1:1
objectId : <objectId>
subtype : error
type : object
}
{
className : MyError
description : MyError: custom message at <anonymous>:1:23 at recurse (test.js:4:10) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at foo (test.js:8:3) at <anonymous>:1:1
objectId : <objectId>
preview : {
description : MyError: custom message at <anonymous>:1:23 at recurse (test.js:4:10) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at foo (test.js:8:3) at <anonymous>:1:1
overflow : false
properties : [
[0] : {
name : stack
type : string
value : Error at <anonymous>:1:23 at recurse (test…) at foo (test.js:8:3) at <anonymous>:1:1
}
]
subtype : error
type : object
}
subtype : error
type : object
}
{
className : MyError
description : MyError: foo at <anonymous>:1:23 at recurse (test.js:4:10) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at foo (test.js:8:3) at <anonymous>:1:1
objectId : <objectId>
preview : {
description : MyError: foo at <anonymous>:1:23 at recurse (test.js:4:10) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at foo (test.js:8:3) at <anonymous>:1:1
overflow : false
properties : [
[0] : {
name : stack
type : string
value : Error: foo at <anonymous>:1:23 at recurse …) at foo (test.js:8:3) at <anonymous>:1:1
}
[1] : {
name : message
type : string
value : foo
}
]
subtype : error
type : object
}
subtype : error
type : object
}
{
className : ErrorWithCustomName
description : NamedError: bar at <anonymous>:1:23 at recurse (test.js:4:10) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at foo (test.js:8:3) at <anonymous>:1:1
objectId : <objectId>
preview : {
description : NamedError: bar at <anonymous>:1:23 at recurse (test.js:4:10) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at foo (test.js:8:3) at <anonymous>:1:1
overflow : false
properties : [
[0] : {
name : name
type : string
value : NamedError
}
[1] : {
name : stack
type : string
value : NamedError: bar at <anonymous>:1:23 at rec…) at foo (test.js:8:3) at <anonymous>:1:1
}
[2] : {
name : message
type : string
value : bar
}
]
subtype : error
type : object
}
subtype : error
type : object
}

View File

@ -0,0 +1,47 @@
// Copyright 2024 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
const {session, contextGroup, Protocol} =
InspectorTest.start('Checks that error.stack works correctly for custom Error subclasses');
contextGroup.addScript(`
function recurse(f, n) {
if (n-- > 0) return recurse(f, n);
return f();
}
function foo(f) {
recurse(f, 5);
}
class MyError extends Error {
get message() { return 'custom message'; }
}
class ErrorWithCustomName extends Error {
name = "NamedError";
}
//# sourceURL=test.js
`);
(async () => {
Protocol.Runtime.onConsoleAPICalled(({ params }) => {
InspectorTest.logMessage(params.args[0]);
});
await Protocol.Runtime.enable();
InspectorTest.logMessage(
(await Protocol.Runtime.evaluate({ expression: 'foo(() => {throw new MyError;})' })).result.exceptionDetails.exception);
InspectorTest.logMessage(
(await Protocol.Runtime.evaluate({ expression: 'foo(() => {throw new MyError("foo");})' })).result.exceptionDetails.exception);
InspectorTest.logMessage(
(await Protocol.Runtime.evaluate({ expression: 'foo(() => {throw new ErrorWithCustomName("bar");})' })).result.exceptionDetails.exception);
await Protocol.Runtime.evaluate({ expression: 'foo(() => console.log(new MyError))' });
await Protocol.Runtime.evaluate({ expression: 'foo(() => console.log(new MyError("foo")))' });
await Protocol.Runtime.evaluate({ expression: 'foo(() => console.log(new ErrorWithCustomName("bar")))' });
InspectorTest.completeTest();
})();

View File

@ -0,0 +1,368 @@
RemoteObject.CustomPreview
Dump custom previews..
{
bodyGetterId : <bodyGetterId>
header : [
[0] : span
[1] : {
}
[2] : Header formatted by 1
[3] : a
]
}
{
id : <messageId>
result : {
result : {
type : object
value : [
[0] : span
[1] : {
}
[2] : Body formatted by 1
[3] : a
[4] : [
[0] : object
[1] : {
className : Object
description : Object
objectId : <objectId>
type : object
}
]
]
}
}
}
{
bodyGetterId : <bodyGetterId>
header : [
[0] : span
[1] : {
}
[2] : Header formatted by 2
[3] : b
]
}
{
id : <messageId>
result : {
result : {
type : object
value : [
[0] : span
[1] : {
}
[2] : Body formatted by 2
[3] : b
]
}
}
}
{
bodyGetterId : <bodyGetterId>
header : [
[0] : span
[1] : {
}
[2] : Header formatted by 1
[3] : c
]
}
{
id : <messageId>
result : {
result : {
type : object
value : [
[0] : span
[1] : {
}
[2] : Body formatted by 1
[3] : c
[4] : [
[0] : object
[1] : {
className : Object
description : Object
objectId : <objectId>
type : object
}
]
]
}
}
}
{
header : [
[0] : span
[1] : {
}
[2] : Formatter with config
[3] : [
[0] : object
[1] : {
className : Object
customPreview : {
bodyGetterId : <bodyGetterId>
header : ["span",{},"Header ","info: ","additional info"]
}
description : Object
objectId : <objectId>
type : object
}
]
]
}
{
bodyGetterId : <bodyGetterId>
header : [
[0] : span
[1] : {
}
[2] : Null body:
[3] : nullBodyTest
]
}
{
id : <messageId>
result : {
result : {
subtype : null
type : object
value : null
}
}
}
Change formatters order and dump again..
{
bodyGetterId : <bodyGetterId>
header : [
[0] : span
[1] : {
}
[2] : Header formatted by 1
[3] : a
]
}
{
id : <messageId>
result : {
result : {
type : object
value : [
[0] : span
[1] : {
}
[2] : Body formatted by 1
[3] : a
[4] : [
[0] : object
[1] : {
className : Object
description : Object
objectId : <objectId>
type : object
}
]
]
}
}
}
{
bodyGetterId : <bodyGetterId>
header : [
[0] : span
[1] : {
}
[2] : Header formatted by 2
[3] : b
]
}
{
id : <messageId>
result : {
result : {
type : object
value : [
[0] : span
[1] : {
}
[2] : Body formatted by 2
[3] : b
]
}
}
}
{
bodyGetterId : <bodyGetterId>
header : [
[0] : span
[1] : {
}
[2] : Header formatted by 2
[3] : c
]
}
{
id : <messageId>
result : {
result : {
type : object
value : [
[0] : span
[1] : {
}
[2] : Body formatted by 2
[3] : c
]
}
}
}
{
header : [
[0] : span
[1] : {
}
[2] : Formatter with config
[3] : [
[0] : object
[1] : {
className : Object
customPreview : {
bodyGetterId : <bodyGetterId>
header : ["span",{},"Header ","info: ","additional info"]
}
description : Object
objectId : <objectId>
type : object
}
]
]
}
{
bodyGetterId : <bodyGetterId>
header : [
[0] : span
[1] : {
}
[2] : Null body:
[3] : nullBodyTest
]
}
{
id : <messageId>
result : {
result : {
subtype : null
type : object
value : null
}
}
}
Test Runtime.getProperties
{
bodyGetterId : <bodyGetterId>
header : [
[0] : span
[1] : {
}
[2] : Header formatted by 1
[3] : a
]
}
{
id : <messageId>
result : {
result : {
type : object
value : [
[0] : span
[1] : {
}
[2] : Body formatted by 1
[3] : a
[4] : [
[0] : object
[1] : {
className : Object
description : Object
objectId : <objectId>
type : object
}
]
]
}
}
}
Try to break custom preview..
{
method : Runtime.consoleAPICalled
params : {
args : [
[0] : {
type : string
value : Custom Formatter Failed: Uncaught 1
}
]
executionContextId : <executionContextId>
timestamp : <timestamp>
type : error
}
}
{
method : Runtime.consoleAPICalled
params : {
args : [
[0] : {
type : string
value : Custom Formatter Failed: Uncaught 1
}
]
executionContextId : <executionContextId>
timestamp : <timestamp>
type : error
}
}
{
method : Runtime.consoleAPICalled
params : {
args : [
[0] : {
type : string
value : Custom Formatter Failed: Uncaught 2
}
]
executionContextId : <executionContextId>
timestamp : <timestamp>
type : error
}
}
{
method : Runtime.consoleAPICalled
params : {
args : [
[0] : {
type : string
value : Custom Formatter Failed: Uncaught 3
}
]
executionContextId : <executionContextId>
timestamp : <timestamp>
type : error
}
}
{
method : Runtime.consoleAPICalled
params : {
args : [
[0] : {
type : string
value : Custom Formatter Failed: Uncaught 4
}
]
executionContextId : <executionContextId>
timestamp : <timestamp>
type : error
}
}

View File

@ -0,0 +1,143 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
const {session, contextGroup, Protocol} =
InspectorTest.start('RemoteObject.CustomPreview');
(async function test() {
contextGroup.addScript(`
var a = {name: 'a'};
var b = {name: 'b'};
var c = {name: 'c'};
a.formattableBy1 = true;
b.formattableBy2 = true;
c.formattableBy1 = true;
c.formattableBy2 = true;
var formatter1 = {
header: (x) => x.formattableBy1 ? ['span', {}, 'Header formatted by 1 ', x.name] : null,
hasBody: () => true,
body: (x) => ['span', {}, 'Body formatted by 1 ', x.name, ['object', {object: {}}]]
};
var formatter2 = {
header: (x) => x.formattableBy2 ? ['span', {}, 'Header formatted by 2 ', x.name] : null,
hasBody: (x) => true,
body: (x) => ['span', {}, 'Body formatted by 2 ', x.name]
};
var configTest = {};
var formatterWithConfig1 = {
header: function(x, config) {
if (x !== configTest || config)
return null;
return ['span', {}, 'Formatter with config ', ['object', {'object': x, 'config': {'info': 'additional info'}}]];
},
hasBody: (x) => false,
body: (x) => { throw 'Unreachable'; }
}
var formatterWithConfig2 = {
header: function(x, config) {
if (x !== configTest || !config)
return null;
return ['span', {}, 'Header ', 'info: ', config.info];
},
hasBody: (x, config) => config && config.info,
body: (x, config) => ['span', {}, 'body', 'info: ', config.info]
}
var nullBodyTest = {name: 'nullBodyTest'};
var formatterWithNullBody = {
header: (x) => x === nullBodyTest ? ['span', {}, 'Null body: ', x.name] : null,
hasBody: (x) => true,
body: (x) => null
}
this.devtoolsFormatters = [formatter1, formatter2, formatterWithConfig1, formatterWithConfig2, formatterWithNullBody];
`);
Protocol.Runtime.enable();
Protocol.Runtime.setCustomObjectFormatterEnabled({enabled: true});
Protocol.Runtime.onConsoleAPICalled(m => InspectorTest.logMessage(m));
InspectorTest.log('Dump custom previews..');
await dumpCustomPreviewForEvaluate(await Protocol.Runtime.evaluate({expression: 'a'}));
await dumpCustomPreviewForEvaluate(await Protocol.Runtime.evaluate({expression: 'b'}));
await dumpCustomPreviewForEvaluate(await Protocol.Runtime.evaluate({expression: 'c'}));
await dumpCustomPreviewForEvaluate(await Protocol.Runtime.evaluate({expression: 'configTest'}));
await dumpCustomPreviewForEvaluate(await Protocol.Runtime.evaluate({expression: 'nullBodyTest'}));
InspectorTest.log('Change formatters order and dump again..');
await Protocol.Runtime.evaluate({
expression: 'this.devtoolsFormatters = [formatter2, formatter1, formatterWithConfig1, formatterWithConfig2, formatterWithNullBody]'
});
await dumpCustomPreviewForEvaluate(await Protocol.Runtime.evaluate({expression: 'a'}));
await dumpCustomPreviewForEvaluate(await Protocol.Runtime.evaluate({expression: 'b'}));
await dumpCustomPreviewForEvaluate(await Protocol.Runtime.evaluate({expression: 'c'}));
await dumpCustomPreviewForEvaluate(await Protocol.Runtime.evaluate({expression: 'configTest'}));
await dumpCustomPreviewForEvaluate(await Protocol.Runtime.evaluate({expression: 'nullBodyTest'}));
InspectorTest.log('Test Runtime.getProperties');
const {result:{result:{objectId}}} = await Protocol.Runtime.evaluate({expression: '({a})'});
const {result:{result}} = await Protocol.Runtime.getProperties({
objectId, ownProperties: true, generatePreview: true});
await dumpCustomPreview(result.find(value => value.name === 'a').value);
InspectorTest.log('Try to break custom preview..');
await Protocol.Runtime.evaluate({
expression: `Object.defineProperty(this, 'devtoolsFormatters', {
get: () => { throw 1; },
configurable: true
})`
});
Protocol.Runtime.evaluate({ expression: '({})', generatePreview: true });
InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());
await Protocol.Runtime.evaluate({
expression: `Object.defineProperty(this, 'devtoolsFormatters', {
get: () => {
const arr = [1];
Object.defineProperty(arr, 0, { get: () => { throw 2; }});
return arr;
},
configurable: true
})`
});
Protocol.Runtime.evaluate({ expression: '({})', generatePreview: true });
InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());
await Protocol.Runtime.evaluate({
expression: `Object.defineProperty(this, 'devtoolsFormatters', {
get: () => [{get header() { throw 3; }}],
configurable: true
})`
});
Protocol.Runtime.evaluate({ expression: '({})', generatePreview: true });
InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());
await Protocol.Runtime.evaluate({
expression: `Object.defineProperty(this, 'devtoolsFormatters', {
get: () => [{header: () => { throw 4; }}],
configurable: true
})`
});
Protocol.Runtime.evaluate({ expression: '({})', generatePreview: true });
InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());
InspectorTest.completeTest();
})()
function dumpCustomPreviewForEvaluate(result) {
return dumpCustomPreview(result.result.result);
}
async function dumpCustomPreview(result) {
const { objectId, customPreview } = result;
if (customPreview.header)
customPreview.header = JSON.parse(customPreview.header);
InspectorTest.logMessage(customPreview);
if (customPreview.bodyGetterId) {
const body = await Protocol.Runtime.callFunctionOn({
objectId,
functionDeclaration: 'function(bodyGetter) { return bodyGetter.call(this); }',
arguments: [ { objectId: customPreview.bodyGetterId } ],
returnByValue: true
});
InspectorTest.logMessage(body);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,107 @@
// Copyright 2023 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
const { session, contextGroup, Protocol } =
InspectorTest.start('RemoteObject.deepSerializedValue');
Protocol.Runtime.enable();
Protocol.Runtime.onConsoleAPICalled(m => InspectorTest.logMessage(m));
InspectorTest.runAsyncTestSuite([
async function PrimitiveValue() {
await testExpression("undefined");
await testExpression("null");
await testExpression("'foo'");
await testExpression("true");
await testExpression("false");
},
async function Number() {
await testExpression("123");
await testExpression("0.56");
await testExpression("-0");
await testExpression("+Infinity");
await testExpression("-Infinity");
await testExpression("NaN");
},
async function BigInt() {
await testExpression("123n");
await testExpression("1234567890n");
},
async function Symbol() {
await testExpression("Symbol('foo')");
},
async function Function() {
await testExpression("function qwe(){}");
await testExpression("()=>{}");
},
async function Array() {
await testExpression("[1,2,undefined]");
await testExpression("new Array(1,2,undefined)");
},
async function RegExp() {
await testExpression("new RegExp('ab+c')");
await testExpression("new RegExp('ab+c', 'ig')");
},
async function Date() {
await testExpression("new Date('Thu Apr 07 2022 16:17:18 GMT')");
await testExpression("new Date('Thu Apr 07 2022 16:17:18 GMT+1100')");
await testExpression("new Date('Thu Apr 07 2022 16:17:18 GMT-1100')");
},
async function Error() {
await testExpression("new Error()");
await testExpression("new Error('qwe')");
},
async function Map() {
await testExpression("new Map([['keyString1', {valueObject1: 1}], [{keyObject2: 2}, 'valueString2'], ['keyString3', new Array()]])");
},
async function WeakMap() {
await testExpression("new WeakMap([[{valueObject1: 1}, 'keyString1'],[{valueObject2: 2}, 'keyString2']])");
},
async function Set() {
await testExpression("new Set([{valueObject1: 1}, 'valueString2', new Array(), undefined])");
},
async function Weakset() {
await testExpression("new WeakSet([{valueObject1: 1}, {valueObject2: 2}])");
},
async function Proxy() {
await testExpression("new Proxy({}, ()=>{})");
},
async function Promise() {
await testExpression("new Promise(()=>{})");
},
async function Typedarray() {
await testExpression("new Uint16Array()");
},
async function ArrayBuffer() {
await testExpression("new ArrayBuffer()");
},
async function Duplicate() {
await testExpression("(()=>{const foo={a: []}; const bar=[1,2]; const result={1: foo, 2: foo, 3: bar, 4: bar}; result.self=result; return result; })()");
},
async function Object() {
// Object.
await testExpression("{nullKey: null, stringKey: 'foo',boolKey: true,numberKey: 123,bigintKey: 123n,symbolKey: Symbol('foo'),functionKey: () => {},arrayKey:[1],undefinedKey:undefined}");
// Object in-depth serialization.
await testExpression("{key_level_1: {key_level_2: {key_level_3: 'value_level_3'}}}");
}]);
async function testExpression(expression) {
const wrappedExpression = `(()=>{const a=${expression}; const b=${expression}; return [a,b,a,b,a,b]})()`
InspectorTest.logMessage("testing expression: "+expression);
InspectorTest.logMessage("Runtime.evaluate");
dumpResult(await Protocol.Runtime.evaluate({
expression: wrappedExpression,
serializationOptions: { serialization: "deep" }
}));
}
function dumpResult(result) {
if (result?.result?.result?.deepSerializedValue) {
InspectorTest.logMessage(result.result.result.deepSerializedValue);
} else {
InspectorTest.log("...no deepSerializedValue...");
InspectorTest.logMessage(result);
}
}

View File

@ -0,0 +1,960 @@
RemoteObject.deepSerializedValue
Running test: PrimitiveValue
testing expression: undefined
Runtime.evaluate
{
type : undefined
}
Runtime.callFunctionOn
{
type : undefined
}
testing expression: null
Runtime.evaluate
{
type : null
}
Runtime.callFunctionOn
{
type : null
}
testing expression: 'foo'
Runtime.evaluate
{
type : string
value : foo
}
Runtime.callFunctionOn
{
type : string
value : foo
}
testing expression: true
Runtime.evaluate
{
type : boolean
value : true
}
Runtime.callFunctionOn
{
type : boolean
value : true
}
testing expression: false
Runtime.evaluate
{
type : boolean
value : false
}
Runtime.callFunctionOn
{
type : boolean
value : false
}
Running test: Number
testing expression: 123
Runtime.evaluate
{
type : number
value : 123
}
Runtime.callFunctionOn
{
type : number
value : 123
}
testing expression: 0.56
Runtime.evaluate
{
type : number
value : 0.56
}
Runtime.callFunctionOn
{
type : number
value : 0.56
}
testing expression: -0
Runtime.evaluate
{
type : number
value : -0
}
Runtime.callFunctionOn
{
type : number
value : -0
}
testing expression: +Infinity
Runtime.evaluate
{
type : number
value : Infinity
}
Runtime.callFunctionOn
{
type : number
value : Infinity
}
testing expression: -Infinity
Runtime.evaluate
{
type : number
value : -Infinity
}
Runtime.callFunctionOn
{
type : number
value : -Infinity
}
testing expression: NaN
Runtime.evaluate
{
type : number
value : NaN
}
Runtime.callFunctionOn
{
type : number
value : NaN
}
Running test: BigInt
testing expression: 123n
Runtime.evaluate
{
type : bigint
value : 123
}
Runtime.callFunctionOn
{
type : bigint
value : 123
}
testing expression: 1234567890n
Runtime.evaluate
{
type : bigint
value : 1234567890
}
Runtime.callFunctionOn
{
type : bigint
value : 1234567890
}
Running test: Symbol
testing expression: Symbol('foo')
Runtime.evaluate
{
type : symbol
}
Runtime.callFunctionOn
{
type : symbol
}
Running test: Function
testing expression: function qwe(){}
Runtime.evaluate
{
type : function
}
Runtime.callFunctionOn
{
type : function
}
testing expression: ()=>{}
Runtime.evaluate
{
type : function
}
Runtime.callFunctionOn
{
type : function
}
Running test: Array
testing expression: [1,2,undefined]
Runtime.evaluate
{
type : array
value : [
[0] : {
type : number
value : 1
}
[1] : {
type : number
value : 2
}
[2] : {
type : undefined
}
]
}
Runtime.callFunctionOn
{
type : array
value : [
[0] : {
type : number
value : 1
}
[1] : {
type : number
value : 2
}
[2] : {
type : undefined
}
]
}
testing expression: new Array(1,2,undefined)
Runtime.evaluate
{
type : array
value : [
[0] : {
type : number
value : 1
}
[1] : {
type : number
value : 2
}
[2] : {
type : undefined
}
]
}
Runtime.callFunctionOn
{
type : array
value : [
[0] : {
type : number
value : 1
}
[1] : {
type : number
value : 2
}
[2] : {
type : undefined
}
]
}
Running test: RegExp
testing expression: new RegExp('ab+c')
Runtime.evaluate
{
type : regexp
value : {
pattern : ab+c
}
}
Runtime.callFunctionOn
{
type : regexp
value : {
pattern : ab+c
}
}
testing expression: new RegExp('ab+c', 'ig')
Runtime.evaluate
{
type : regexp
value : {
flags : gi
pattern : ab+c
}
}
Runtime.callFunctionOn
{
type : regexp
value : {
flags : gi
pattern : ab+c
}
}
Running test: Date
testing expression: new Date('Thu Apr 07 2022 16:17:18 GMT')
Runtime.evaluate
{
type : date
value : 2022-04-07T16:17:18.000Z
}
Runtime.callFunctionOn
{
type : date
value : 2022-04-07T16:17:18.000Z
}
testing expression: new Date('Thu Apr 07 2022 16:17:18 GMT+1100')
Runtime.evaluate
{
type : date
value : 2022-04-07T05:17:18.000Z
}
Runtime.callFunctionOn
{
type : date
value : 2022-04-07T05:17:18.000Z
}
testing expression: new Date('Thu Apr 07 2022 16:17:18 GMT-1100')
Runtime.evaluate
{
type : date
value : 2022-04-08T03:17:18.000Z
}
Runtime.callFunctionOn
{
type : date
value : 2022-04-08T03:17:18.000Z
}
Running test: Error
testing expression: new Error()
Runtime.evaluate
{
type : error
}
Runtime.callFunctionOn
{
type : error
}
testing expression: new Error('qwe')
Runtime.evaluate
{
type : error
}
Runtime.callFunctionOn
{
type : error
}
Running test: Map
testing expression: new Map([['keyString1', {valueObject1: 1}], [{keyObject2: 2}, 'valueString2'], ['keyString3', new Array()]])
Runtime.evaluate
{
type : map
value : [
[0] : [
[0] : keyString1
[1] : {
type : object
value : [
[0] : [
[0] : valueObject1
[1] : {
type : number
value : 1
}
]
]
}
]
[1] : [
[0] : {
type : object
value : [
[0] : [
[0] : keyObject2
[1] : {
type : number
value : 2
}
]
]
}
[1] : {
type : string
value : valueString2
}
]
[2] : [
[0] : keyString3
[1] : {
type : array
value : [
]
}
]
]
}
Runtime.callFunctionOn
{
type : map
value : [
[0] : [
[0] : keyString1
[1] : {
type : object
value : [
[0] : [
[0] : valueObject1
[1] : {
type : number
value : 1
}
]
]
}
]
[1] : [
[0] : {
type : object
value : [
[0] : [
[0] : keyObject2
[1] : {
type : number
value : 2
}
]
]
}
[1] : {
type : string
value : valueString2
}
]
[2] : [
[0] : keyString3
[1] : {
type : array
value : [
]
}
]
]
}
Running test: WeakMap
testing expression: new WeakMap([[{valueObject1: 1}, 'keyString1'],[{valueObject2: 2}, 'keyString2']])
Runtime.evaluate
{
type : weakmap
}
Runtime.callFunctionOn
{
type : weakmap
}
Running test: Set
testing expression: new Set([{valueObject1: 1}, 'valueString2', new Array(), undefined])
Runtime.evaluate
{
type : set
value : [
[0] : {
type : object
value : [
[0] : [
[0] : valueObject1
[1] : {
type : number
value : 1
}
]
]
}
[1] : {
type : string
value : valueString2
}
[2] : {
type : array
value : [
]
}
[3] : {
type : undefined
}
]
}
Runtime.callFunctionOn
{
type : set
value : [
[0] : {
type : object
value : [
[0] : [
[0] : valueObject1
[1] : {
type : number
value : 1
}
]
]
}
[1] : {
type : string
value : valueString2
}
[2] : {
type : array
value : [
]
}
[3] : {
type : undefined
}
]
}
Running test: Weakset
testing expression: new WeakSet([{valueObject1: 1}, {valueObject2: 2}])
Runtime.evaluate
{
type : weakset
}
Runtime.callFunctionOn
{
type : weakset
}
Running test: Proxy
testing expression: new Proxy({}, ()=>{})
Runtime.evaluate
{
type : proxy
}
Runtime.callFunctionOn
{
type : proxy
}
Running test: Promise
testing expression: new Promise(()=>{})
Runtime.evaluate
{
type : promise
}
Runtime.callFunctionOn
{
type : promise
}
Running test: Typedarray
testing expression: new Uint16Array()
Runtime.evaluate
{
type : typedarray
}
Runtime.callFunctionOn
{
type : typedarray
}
Running test: ArrayBuffer
testing expression: new ArrayBuffer()
Runtime.evaluate
{
type : arraybuffer
}
Runtime.callFunctionOn
{
type : arraybuffer
}
Running test: Duplicate
testing expression: (()=>{const foo={a: []}; const bar=[1,2]; const result={1: foo, 2: foo, 3: bar, 4: bar}; result.self=result; return result; })()
Runtime.evaluate
{
type : object
value : [
[0] : [
[0] : 1
[1] : {
type : object
value : [
[0] : [
[0] : a
[1] : {
type : array
value : [
]
}
]
]
weakLocalObjectReference : 1
}
]
[1] : [
[0] : 2
[1] : {
type : object
weakLocalObjectReference : 1
}
]
[2] : [
[0] : 3
[1] : {
type : array
value : [
[0] : {
type : number
value : 1
}
[1] : {
type : number
value : 2
}
]
weakLocalObjectReference : 2
}
]
[3] : [
[0] : 4
[1] : {
type : array
weakLocalObjectReference : 2
}
]
[4] : [
[0] : self
[1] : {
type : object
weakLocalObjectReference : 3
}
]
]
weakLocalObjectReference : 3
}
Runtime.callFunctionOn
{
type : object
value : [
[0] : [
[0] : 1
[1] : {
type : object
value : [
[0] : [
[0] : a
[1] : {
type : array
value : [
]
}
]
]
weakLocalObjectReference : 1
}
]
[1] : [
[0] : 2
[1] : {
type : object
weakLocalObjectReference : 1
}
]
[2] : [
[0] : 3
[1] : {
type : array
value : [
[0] : {
type : number
value : 1
}
[1] : {
type : number
value : 2
}
]
weakLocalObjectReference : 2
}
]
[3] : [
[0] : 4
[1] : {
type : array
weakLocalObjectReference : 2
}
]
[4] : [
[0] : self
[1] : {
type : object
weakLocalObjectReference : 3
}
]
]
weakLocalObjectReference : 3
}
Running test: Object
testing expression: {nullKey: null, stringKey: 'foo',boolKey: true,numberKey: 123,bigintKey: 123n,symbolKey: Symbol('foo'),functionKey: () => {},arrayKey:[1],undefinedKey:undefined}
Runtime.evaluate
{
type : object
value : [
[0] : [
[0] : nullKey
[1] : {
type : null
}
]
[1] : [
[0] : stringKey
[1] : {
type : string
value : foo
}
]
[2] : [
[0] : boolKey
[1] : {
type : boolean
value : true
}
]
[3] : [
[0] : numberKey
[1] : {
type : number
value : 123
}
]
[4] : [
[0] : bigintKey
[1] : {
type : bigint
value : 123
}
]
[5] : [
[0] : symbolKey
[1] : {
type : symbol
}
]
[6] : [
[0] : functionKey
[1] : {
type : function
}
]
[7] : [
[0] : arrayKey
[1] : {
type : array
value : [
[0] : {
type : number
value : 1
}
]
}
]
[8] : [
[0] : undefinedKey
[1] : {
type : undefined
}
]
]
}
Runtime.callFunctionOn
{
type : object
value : [
[0] : [
[0] : nullKey
[1] : {
type : null
}
]
[1] : [
[0] : stringKey
[1] : {
type : string
value : foo
}
]
[2] : [
[0] : boolKey
[1] : {
type : boolean
value : true
}
]
[3] : [
[0] : numberKey
[1] : {
type : number
value : 123
}
]
[4] : [
[0] : bigintKey
[1] : {
type : bigint
value : 123
}
]
[5] : [
[0] : symbolKey
[1] : {
type : symbol
}
]
[6] : [
[0] : functionKey
[1] : {
type : function
}
]
[7] : [
[0] : arrayKey
[1] : {
type : array
value : [
[0] : {
type : number
value : 1
}
]
}
]
[8] : [
[0] : undefinedKey
[1] : {
type : undefined
}
]
]
}
testing expression: {key_level_1: {key_level_2: {key_level_3: 'value_level_3'}}}
Runtime.evaluate
{
type : object
value : [
[0] : [
[0] : key_level_1
[1] : {
type : object
value : [
[0] : [
[0] : key_level_2
[1] : {
type : object
value : [
[0] : [
[0] : key_level_3
[1] : {
type : string
value : value_level_3
}
]
]
}
]
]
}
]
]
}
Runtime.callFunctionOn
{
type : object
value : [
[0] : [
[0] : key_level_1
[1] : {
type : object
value : [
[0] : [
[0] : key_level_2
[1] : {
type : object
value : [
[0] : [
[0] : key_level_3
[1] : {
type : string
value : value_level_3
}
]
]
}
]
]
}
]
]
}
testing expression: {1: 'value'}
Runtime.evaluate
{
type : object
value : [
[0] : [
[0] : 1
[1] : {
type : string
value : value
}
]
]
}
Runtime.callFunctionOn
{
type : object
value : [
[0] : [
[0] : 1
[1] : {
type : string
value : value
}
]
]
}
testing expression: {'1': 'value'}
Runtime.evaluate
{
type : object
value : [
[0] : [
[0] : 1
[1] : {
type : string
value : value
}
]
]
}
Runtime.callFunctionOn
{
type : object
value : [
[0] : [
[0] : 1
[1] : {
type : string
value : value
}
]
]
}
testing expression: (()=>{const s = Symbol('foo'); const a={}; a[s]='symbol_value'; return a;})()
Runtime.evaluate
{
type : object
value : [
]
}
Runtime.callFunctionOn
{
type : object
value : [
]
}

View File

@ -0,0 +1,130 @@
// Copyright 2023 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
const { session, contextGroup, Protocol } =
InspectorTest.start('RemoteObject.deepSerializedValue');
Protocol.Runtime.enable();
Protocol.Runtime.onConsoleAPICalled(m => InspectorTest.logMessage(m));
InspectorTest.runAsyncTestSuite([
async function PrimitiveValue() {
await testExpression("undefined");
await testExpression("null");
await testExpression("'foo'");
await testExpression("true");
await testExpression("false");
},
async function Number() {
await testExpression("123");
await testExpression("0.56");
await testExpression("-0");
await testExpression("+Infinity");
await testExpression("-Infinity");
await testExpression("NaN");
},
async function BigInt() {
await testExpression("123n");
await testExpression("1234567890n");
},
async function Symbol() {
await testExpression("Symbol('foo')");
},
async function Function() {
await testExpression("function qwe(){}");
await testExpression("()=>{}");
},
async function Array() {
await testExpression("[1,2,undefined]");
await testExpression("new Array(1,2,undefined)");
},
async function RegExp() {
await testExpression("new RegExp('ab+c')");
await testExpression("new RegExp('ab+c', 'ig')");
},
async function Date() {
await testExpression("new Date('Thu Apr 07 2022 16:17:18 GMT')");
await testExpression("new Date('Thu Apr 07 2022 16:17:18 GMT+1100')");
await testExpression("new Date('Thu Apr 07 2022 16:17:18 GMT-1100')");
},
async function Error() {
await testExpression("new Error()");
await testExpression("new Error('qwe')");
},
async function Map() {
await testExpression("new Map([['keyString1', {valueObject1: 1}], [{keyObject2: 2}, 'valueString2'], ['keyString3', new Array()]])");
},
async function WeakMap() {
await testExpression("new WeakMap([[{valueObject1: 1}, 'keyString1'],[{valueObject2: 2}, 'keyString2']])");
},
async function Set() {
await testExpression("new Set([{valueObject1: 1}, 'valueString2', new Array(), undefined])");
},
async function Weakset() {
await testExpression("new WeakSet([{valueObject1: 1}, {valueObject2: 2}])");
},
async function Proxy() {
await testExpression("new Proxy({}, ()=>{})");
},
async function Promise() {
await testExpression("new Promise(()=>{})");
},
async function Typedarray() {
await testExpression("new Uint16Array()");
},
async function ArrayBuffer() {
await testExpression("new ArrayBuffer()");
},
async function Duplicate() {
await testExpression("(()=>{const foo={a: []}; const bar=[1,2]; const result={1: foo, 2: foo, 3: bar, 4: bar}; result.self=result; return result; })()");
},
async function Object() {
// Object.
await testExpression("{nullKey: null, stringKey: 'foo',boolKey: true,numberKey: 123,bigintKey: 123n,symbolKey: Symbol('foo'),functionKey: () => {},arrayKey:[1],undefinedKey:undefined}");
// Object in-depth serialization.
await testExpression("{key_level_1: {key_level_2: {key_level_3: 'value_level_3'}}}");
// Object with number property name.
await testExpression("{1: 'value'}");
// Object with string number property name.
await testExpression("{'1': 'value'}");
// Object with a symbol as a property name.
await testExpression("(()=>{const s = Symbol('foo'); const a={}; a[s]='symbol_value'; return a;})()");
}]);
async function serializeViaEvaluate(expression) {
return await Protocol.Runtime.evaluate({
expression: "("+expression+")",
serializationOptions: { serialization: "deep" }
});
}
async function serializeViaCallFunctionOn(expression) {
const objectId = (await Protocol.Runtime.evaluate({
expression: "({})",
})).result.result.objectId;
return await Protocol.Runtime.callFunctionOn({
functionDeclaration: "()=>{return " + expression + "}",
objectId,
serializationOptions: { serialization: "deep" }
});
}
async function testExpression(expression) {
InspectorTest.logMessage("testing expression: "+expression);
InspectorTest.logMessage("Runtime.evaluate");
dumpResult(await serializeViaEvaluate(expression));
InspectorTest.logMessage("Runtime.callFunctionOn");
dumpResult(await serializeViaCallFunctionOn(expression));
}
function dumpResult(result) {
if (result?.result?.result?.deepSerializedValue) {
InspectorTest.logMessage(result.result.result.deepSerializedValue);
} else {
InspectorTest.log("...no deepSerializedValue...");
InspectorTest.logMessage(result);
}
}

View File

@ -0,0 +1,45 @@
Checks that async stack is captured when Runtime.setAsyncCallStackDepth is called with an argument greater than zero.
{
callFrames : [
[0] : {
columnNumber : 8
functionName :
lineNumber : 0
scriptId : <scriptId>
url :
}
]
parent : {
callFrames : [
[0] : {
columnNumber : 2
functionName : test
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[1] : {
columnNumber : 0
functionName :
lineNumber : 0
scriptId : <scriptId>
url : expr.js
}
]
description : setTimeout
}
}
{
callFrames : [
[0] : {
columnNumber : 32
functionName :
lineNumber : 0
scriptId : <scriptId>
url :
}
]
parentId : {
id : <id>
}
}

View File

@ -0,0 +1,20 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
const {session, contextGroup, Protocol} = InspectorTest.start(
'Checks that async stack is captured when Runtime.setAsyncCallStackDepth is called with an argument greater than zero.');
Protocol.Runtime.enable();
Protocol.Runtime.onConsoleAPICalled(
message => InspectorTest.logMessage(message.params.stackTrace));
contextGroup.addScript(`
async function test() {
setTimeout('console.trace("async"); console.log("no-async");', 0);
}
//# sourceURL=test.js`);
Protocol.Runtime.setAsyncCallStackDepth({maxDepth: 10});
Protocol.Runtime.evaluate({ expression: 'test()//# sourceURL=expr.js'})
.then(InspectorTest.completeTest);

View File

@ -0,0 +1,66 @@
Checks that Error objects capture the correct async continuation
Running test: testErrorStackWithRuntimeEnabled
{
id : <messageId>
result : {
exceptionDetails : {
columnNumber : 10
exception : {
className : Error
description : Error at generateError (test.js:4:10) at async foo (test.js:8:10) at async bar (test.js:12:17)
objectId : <objectId>
subtype : error
type : object
}
exceptionId : <exceptionId>
lineNumber : 4
scriptId : <scriptId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 9
functionName : generateError
lineNumber : 3
scriptId : <scriptId>
url : test.js
}
]
parent : {
callFrames : [
[0] : {
columnNumber : 15
functionName : foo
lineNumber : 7
scriptId : <scriptId>
url : test.js
}
[1] : {
columnNumber : 22
functionName : bar
lineNumber : 11
scriptId : <scriptId>
url : test.js
}
[2] : {
columnNumber : 0
functionName :
lineNumber : 0
scriptId : <scriptId>
url :
}
]
description : await
}
}
text : Uncaught (in promise) Error
}
result : {
className : Error
description : Error at generateError (test.js:4:10) at async foo (test.js:8:10) at async bar (test.js:12:17)
objectId : <objectId>
subtype : error
type : object
}
}
}

View File

@ -0,0 +1,35 @@
// Copyright 2024 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
const {session, contextGroup, Protocol} = InspectorTest.start(
'Checks that Error objects capture the correct async continuation');
contextGroup.addScript(`
async function generateError() {
await 1;
return new Error();
}
async function foo() {
return await generateError();
}
async function bar() {
const error = await foo();
throw error;
}
//# sourceURL=test.js
`);
InspectorTest.runAsyncTestSuite([
async function testErrorStackWithRuntimeEnabled() {
await Promise.all([
Protocol.Runtime.enable(),
Protocol.Runtime.setAsyncCallStackDepth({maxDepth: 10}),
]);
InspectorTest.logMessage(await Protocol.Runtime.evaluate(
{awaitPromise: true, expression: 'bar()'}));
await Protocol.Runtime.disable();
},
]);

View File

@ -0,0 +1,420 @@
Checks that error.stack works correctly
Running test: testErrorStackWithRuntimeDisabled
{
id : <messageId>
result : {
exceptionDetails : {
columnNumber : 4
exception : {
className : Error
description : Error: Thrown from foo! at test.js:9:11 at recurse (test.js:4:10) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23)
objectId : <objectId>
subtype : error
type : object
}
exceptionId : <exceptionId>
lineNumber : 8
scriptId : <scriptId>
text : Uncaught
}
result : {
className : Error
description : Error: Thrown from foo! at test.js:9:11 at recurse (test.js:4:10) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23)
objectId : <objectId>
subtype : error
type : object
}
}
}
Running test: testErrorStackWithRuntimeEnabled
{
id : <messageId>
result : {
exceptionDetails : {
columnNumber : 4
exception : {
className : Error
description : Error: Thrown from foo! at test.js:9:11 at recurse (test.js:4:10) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23)
objectId : <objectId>
subtype : error
type : object
}
exceptionId : <exceptionId>
lineNumber : 8
scriptId : <scriptId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 10
functionName :
lineNumber : 8
scriptId : <scriptId>
url : test.js
}
[1] : {
columnNumber : 9
functionName : recurse
lineNumber : 3
scriptId : <scriptId>
url : test.js
}
[2] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[3] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[4] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[5] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[6] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[7] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[8] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[9] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[10] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[11] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[12] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[13] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[14] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[15] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[16] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[17] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[18] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[19] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[20] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[21] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[22] : {
columnNumber : 2
functionName : foo
lineNumber : 7
scriptId : <scriptId>
url : test.js
}
[23] : {
columnNumber : 0
functionName :
lineNumber : 0
scriptId : <scriptId>
url :
}
]
}
text : Uncaught
}
result : {
className : Error
description : Error: Thrown from foo! at test.js:9:11 at recurse (test.js:4:10) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23)
objectId : <objectId>
subtype : error
type : object
}
}
}
{
id : <messageId>
result : {
exceptionDetails : {
columnNumber : 4
exception : {
className : Error
description : Error: Thrown from foo! at test.js:9:11 at recurse (test.js:4:10) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23)
objectId : <objectId>
subtype : error
type : object
}
exceptionId : <exceptionId>
lineNumber : 8
scriptId : <scriptId>
text : Uncaught
}
result : {
className : Error
description : Error: Thrown from foo! at test.js:9:11 at recurse (test.js:4:10) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23)
objectId : <objectId>
subtype : error
type : object
}
}
}
{
id : <messageId>
result : {
exceptionDetails : {
columnNumber : 4
exception : {
className : Error
description : Error: Thrown from foo! at test.js:9:11 at recurse (test.js:4:10) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23)
objectId : <objectId>
subtype : error
type : object
}
exceptionId : <exceptionId>
lineNumber : 8
scriptId : <scriptId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 10
functionName :
lineNumber : 8
scriptId : <scriptId>
url : test.js
}
[1] : {
columnNumber : 9
functionName : recurse
lineNumber : 3
scriptId : <scriptId>
url : test.js
}
[2] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[3] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[4] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
]
}
text : Uncaught
}
result : {
className : Error
description : Error: Thrown from foo! at test.js:9:11 at recurse (test.js:4:10) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23)
objectId : <objectId>
subtype : error
type : object
}
}
}
{
id : <messageId>
result : {
exceptionDetails : {
columnNumber : 4
exception : {
className : Error
description : Error: Thrown from foo! at test.js:9:11 at recurse (test.js:4:10) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23)
objectId : <objectId>
subtype : error
type : object
}
exceptionId : <exceptionId>
lineNumber : 8
scriptId : <scriptId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 10
functionName :
lineNumber : 8
scriptId : <scriptId>
url : test.js
}
[1] : {
columnNumber : 9
functionName : recurse
lineNumber : 3
scriptId : <scriptId>
url : test.js
}
[2] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[3] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[4] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[5] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[6] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[7] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[8] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[9] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
]
}
text : Uncaught
}
result : {
className : Error
description : Error: Thrown from foo! at test.js:9:11 at recurse (test.js:4:10) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23)
objectId : <objectId>
subtype : error
type : object
}
}
}

View File

@ -0,0 +1,820 @@
Checks that Error.stackTraceLimit works correctly
Running test: testErrorStackTraceLimitWithRuntimeDisabled
{
id : <messageId>
result : {
exceptionDetails : {
columnNumber : 4
exception : {
className : Error
description : Error: Thrown from foo! at test.js:9:11 at recurse (test.js:4:10)
objectId : <objectId>
subtype : error
type : object
}
exceptionId : <exceptionId>
lineNumber : 8
scriptId : <scriptId>
text : Uncaught
}
result : {
className : Error
description : Error: Thrown from foo! at test.js:9:11 at recurse (test.js:4:10)
objectId : <objectId>
subtype : error
type : object
}
}
}
Running test: testErrorStackTraceLimitWithRuntimeEnabled
{
id : <messageId>
result : {
exceptionDetails : {
columnNumber : 4
exception : {
className : Error
description : Error: Thrown from foo! at test.js:9:11 at recurse (test.js:4:10)
objectId : <objectId>
subtype : error
type : object
}
exceptionId : <exceptionId>
lineNumber : 8
scriptId : <scriptId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 10
functionName :
lineNumber : 8
scriptId : <scriptId>
url : test.js
}
[1] : {
columnNumber : 9
functionName : recurse
lineNumber : 3
scriptId : <scriptId>
url : test.js
}
[2] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[3] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[4] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[5] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[6] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[7] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[8] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[9] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[10] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[11] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[12] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[13] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[14] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[15] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[16] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[17] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[18] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[19] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[20] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[21] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[22] : {
columnNumber : 2
functionName : foo
lineNumber : 7
scriptId : <scriptId>
url : test.js
}
[23] : {
columnNumber : 0
functionName :
lineNumber : 0
scriptId : <scriptId>
url :
}
]
}
text : Uncaught
}
result : {
className : Error
description : Error: Thrown from foo! at test.js:9:11 at recurse (test.js:4:10)
objectId : <objectId>
subtype : error
type : object
}
}
}
{
id : <messageId>
result : {
exceptionDetails : {
columnNumber : 4
exception : {
className : Error
description : Error: Thrown from foo!
objectId : <objectId>
subtype : error
type : object
}
exceptionId : <exceptionId>
lineNumber : 8
scriptId : <scriptId>
text : Uncaught
}
result : {
className : Error
description : Error: Thrown from foo!
objectId : <objectId>
subtype : error
type : object
}
}
}
{
id : <messageId>
result : {
exceptionDetails : {
columnNumber : 4
exception : {
className : Error
description : Error: Thrown from foo! at test.js:9:11 at recurse (test.js:4:10) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23)
objectId : <objectId>
subtype : error
type : object
}
exceptionId : <exceptionId>
lineNumber : 8
scriptId : <scriptId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 10
functionName :
lineNumber : 8
scriptId : <scriptId>
url : test.js
}
[1] : {
columnNumber : 9
functionName : recurse
lineNumber : 3
scriptId : <scriptId>
url : test.js
}
[2] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[3] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[4] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
]
}
text : Uncaught
}
result : {
className : Error
description : Error: Thrown from foo! at test.js:9:11 at recurse (test.js:4:10) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23)
objectId : <objectId>
subtype : error
type : object
}
}
}
{
id : <messageId>
result : {
exceptionDetails : {
columnNumber : 4
exception : {
className : Error
description : Error: Thrown from foo! at test.js:9:11 at recurse (test.js:4:10) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23)
objectId : <objectId>
subtype : error
type : object
}
exceptionId : <exceptionId>
lineNumber : 8
scriptId : <scriptId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 10
functionName :
lineNumber : 8
scriptId : <scriptId>
url : test.js
}
[1] : {
columnNumber : 9
functionName : recurse
lineNumber : 3
scriptId : <scriptId>
url : test.js
}
[2] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[3] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[4] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[5] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[6] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[7] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[8] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[9] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
]
}
text : Uncaught
}
result : {
className : Error
description : Error: Thrown from foo! at test.js:9:11 at recurse (test.js:4:10) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23) at recurse (test.js:3:23)
objectId : <objectId>
subtype : error
type : object
}
}
}
Running test: testErrorStackTraceLimitNonNumber
{
id : <messageId>
result : {
exceptionDetails : {
columnNumber : 4
exception : {
className : Error
description : Error: Thrown from foo!
objectId : <objectId>
subtype : error
type : object
}
exceptionId : <exceptionId>
lineNumber : 8
scriptId : <scriptId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 10
functionName :
lineNumber : 8
scriptId : <scriptId>
url : test.js
}
[1] : {
columnNumber : 9
functionName : recurse
lineNumber : 3
scriptId : <scriptId>
url : test.js
}
[2] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[3] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[4] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[5] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[6] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[7] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[8] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[9] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[10] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[11] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[12] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[13] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[14] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[15] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[16] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[17] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[18] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[19] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[20] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[21] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[22] : {
columnNumber : 2
functionName : foo
lineNumber : 7
scriptId : <scriptId>
url : test.js
}
[23] : {
columnNumber : 0
functionName :
lineNumber : 0
scriptId : <scriptId>
url :
}
]
}
text : Uncaught
}
result : {
className : Error
description : Error: Thrown from foo!
objectId : <objectId>
subtype : error
type : object
}
}
}
Running test: testErrorStackTraceLimitDeleted
{
id : <messageId>
result : {
exceptionDetails : {
columnNumber : 4
exception : {
className : Error
description : Error: Thrown from foo!
objectId : <objectId>
subtype : error
type : object
}
exceptionId : <exceptionId>
lineNumber : 8
scriptId : <scriptId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 10
functionName :
lineNumber : 8
scriptId : <scriptId>
url : test.js
}
[1] : {
columnNumber : 9
functionName : recurse
lineNumber : 3
scriptId : <scriptId>
url : test.js
}
[2] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[3] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[4] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[5] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[6] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[7] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[8] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[9] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[10] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[11] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[12] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[13] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[14] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[15] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[16] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[17] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[18] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[19] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[20] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[21] : {
columnNumber : 22
functionName : recurse
lineNumber : 2
scriptId : <scriptId>
url : test.js
}
[22] : {
columnNumber : 2
functionName : foo
lineNumber : 7
scriptId : <scriptId>
url : test.js
}
[23] : {
columnNumber : 0
functionName :
lineNumber : 0
scriptId : <scriptId>
url :
}
]
}
text : Uncaught
}
result : {
className : Error
description : Error: Thrown from foo!
objectId : <objectId>
subtype : error
type : object
}
}
}

View File

@ -0,0 +1,61 @@
// Copyright 2022 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
const {session, contextGroup, Protocol} =
InspectorTest.start('Checks that Error.stackTraceLimit works correctly');
contextGroup.addScript(`
function recurse(f, n) {
if (n-- > 0) return recurse(f, n);
return f();
}
function foo() {
recurse(() => {
throw new Error('Thrown from foo!');
}, 20);
}
//# sourceURL=test.js
`);
InspectorTest.runAsyncTestSuite([
async function testErrorStackTraceLimitWithRuntimeDisabled() {
await Protocol.Runtime.evaluate({expression: 'Error.stackTraceLimit = 2'});
InspectorTest.logMessage(
await Protocol.Runtime.evaluate({expression: 'foo()'}));
},
async function testErrorStackTraceLimitWithRuntimeEnabled() {
await Protocol.Runtime.enable();
await Protocol.Runtime.evaluate({expression: 'Error.stackTraceLimit = 2'});
InspectorTest.logMessage(
await Protocol.Runtime.evaluate({expression: 'foo()'}));
for (let size = 0; size <= 10; size += 5) {
await Protocol.Runtime.evaluate(
{expression: `Error.stackTraceLimit = ${size}`});
await Protocol.Runtime.setMaxCallStackSizeToCapture({size});
InspectorTest.logMessage(
await Protocol.Runtime.evaluate({expression: 'foo()'}));
}
await Protocol.Runtime.disable();
},
async function testErrorStackTraceLimitNonNumber() {
await Protocol.Runtime.enable();
await Protocol.Runtime.evaluate(
{expression: 'Error.stackTraceLimit = "Invalid"'});
InspectorTest.logMessage(
await Protocol.Runtime.evaluate({expression: 'foo()'}));
await Protocol.Runtime.disable();
},
async function testErrorStackTraceLimitDeleted() {
await Protocol.Runtime.enable();
await Protocol.Runtime.evaluate(
{expression: 'delete Error.stackTraceLimit'});
InspectorTest.logMessage(
await Protocol.Runtime.evaluate({expression: 'foo()'}));
await Protocol.Runtime.disable();
}
]);

View File

@ -0,0 +1,39 @@
// Copyright 2022 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
const {session, contextGroup, Protocol} =
InspectorTest.start('Checks that error.stack works correctly');
contextGroup.addScript(`
function recurse(f, n) {
if (n-- > 0) return recurse(f, n);
return f();
}
function foo() {
recurse(() => {
throw new Error('Thrown from foo!');
}, 20);
}
//# sourceURL=test.js
`);
InspectorTest.runAsyncTestSuite([
async function testErrorStackWithRuntimeDisabled() {
InspectorTest.logMessage(
await Protocol.Runtime.evaluate({expression: 'foo()'}));
},
async function testErrorStackWithRuntimeEnabled() {
await Protocol.Runtime.enable();
InspectorTest.logMessage(
await Protocol.Runtime.evaluate({expression: 'foo()'}));
for (let size = 0; size <= 10; size += 5) {
await Protocol.Runtime.setMaxCallStackSizeToCapture({size});
InspectorTest.logMessage(
await Protocol.Runtime.evaluate({expression: 'foo()'}));
}
await Protocol.Runtime.disable();
},
]);

View File

@ -0,0 +1,268 @@
Checks basic ES6 modules support.
{
method : Debugger.scriptParsed
params : {
buildId :
embedderName : module1
endColumn : 17
endLine : 5
executionContextId : <executionContextId>
hasSourceURL : false
hash : 691860c2718c7dc1093d2933a3a71fe62c25948d592f2cadeee30f2f130c0a00
isLiveEdit : false
isModule : true
length : 83
scriptId : <scriptId>
scriptLanguage : JavaScript
sourceMapURL :
startColumn : 0
startLine : 0
url : module1
}
}
{
method : Debugger.scriptParsed
params : {
buildId :
embedderName : module2
endColumn : 17
endLine : 5
executionContextId : <executionContextId>
hasSourceURL : false
hash : 406cbebea0b200671431320fca58b34225270aa55c47756656a50ef999b24825
isLiveEdit : false
isModule : true
length : 84
scriptId : <scriptId>
scriptLanguage : JavaScript
sourceMapURL :
startColumn : 0
startLine : 0
url : module2
}
}
{
method : Debugger.scriptParsed
params : {
buildId :
embedderName : module3
endColumn : 0
endLine : 11
executionContextId : <executionContextId>
hasSourceURL : false
hash : d719e141b8fa8c07426816ce46ddf65ed0474667b2588300d3e9ec491017e989
isLiveEdit : false
isModule : true
length : 286
scriptId : <scriptId>
scriptLanguage : JavaScript
sourceMapURL :
startColumn : 0
startLine : 0
url : module3
}
}
console.log(module1)
foo (module1:2:10)
(anonymous) (module3:5:12)
console.log(42)
(anonymous) (module3:5:8)
console.log(module2)
foo (module2:2:10)
(anonymous) (module3:6:12)
console.log(239)
(anonymous) (module3:6:8)
{
method : Debugger.paused
params : {
callFrames : [
[0] : {
callFrameId : <callFrameId>
canBeRestarted : false
functionLocation : {
columnNumber : 0
lineNumber : 0
scriptId : <scriptId>
}
functionName :
location : {
columnNumber : 0
lineNumber : 9
scriptId : <scriptId>
}
scopeChain : [
[0] : {
endLocation : {
columnNumber : 0
lineNumber : 11
scriptId : <scriptId>
}
object : {
className : Object
description : Object
objectId : <objectId>
type : object
}
startLocation : {
columnNumber : 0
lineNumber : 0
scriptId : <scriptId>
}
type : module
}
[1] : {
object : {
className : global
description : global
objectId : <objectId>
type : object
}
type : global
}
]
this : {
type : undefined
}
url :
}
]
hitBreakpoints : [
]
reason : other
}
}
{
id : <messageId>
result : {
result : [
[0] : {
configurable : true
enumerable : true
isOwn : true
name : foo1
value : {
className : Function
description : function foo() { console.log('module1'); return 42; }
objectId : <objectId>
type : function
}
writable : true
}
[1] : {
configurable : true
enumerable : true
isOwn : true
name : foo2
value : {
className : Function
description : function foo() { console.log('module2'); return 239; }
objectId : <objectId>
type : function
}
writable : true
}
[2] : {
configurable : true
enumerable : true
isOwn : true
name : foo3
value : {
className : Module
description : Module
objectId : <objectId>
type : object
}
writable : true
}
[3] : {
configurable : true
enumerable : true
isOwn : true
name : a1
value : {
description : 1
type : number
value : 1
}
writable : true
}
[4] : {
configurable : true
enumerable : true
isOwn : true
name : a2
value : {
description : 2
type : number
value : 2
}
writable : true
}
]
}
}
{
method : Debugger.scriptFailedToParse
params : {
buildId :
embedderName : module4
endColumn : 1
endLine : 0
executionContextId : <executionContextId>
hasSourceURL : false
hash : d10b36aa74a59bcf4a88185837f658afaf3646eff2bb16c3928d0e9335e945d2
isModule : true
length : 1
scriptId : <scriptId>
scriptLanguage : JavaScript
sourceMapURL :
startColumn : 0
startLine : 0
url : module4
}
}
{
method : Runtime.exceptionThrown
params : {
exceptionDetails : {
columnNumber : 0
exception : {
className : SyntaxError
description : SyntaxError: Unexpected token '}'
objectId : <objectId>
preview : {
description : SyntaxError: Unexpected token '}'
overflow : false
properties : [
[0] : {
name : stack
type : string
value : SyntaxError: Unexpected token '}'
}
[1] : {
name : message
type : string
value : Unexpected token '}'
}
]
subtype : error
type : object
}
subtype : error
type : object
}
exceptionId : <exceptionId>
executionContextId : <executionContextId>
lineNumber : 0
scriptId : <scriptId>
text : Uncaught SyntaxError: Unexpected token '}'
url : module4
}
timestamp : <timestamp>
}
}
queryObjects returns Array(N)

View File

@ -0,0 +1,79 @@
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
let {session, contextGroup, Protocol} = InspectorTest.start('Checks basic ES6 modules support.');
var module1 = `
export function foo() {
console.log('module1');
return 42;
}
export let a1 = 1`;
var module2 = `
export function foo() {
console.log('module2');
return 239;
}
export let a2 = 2`;
var module3 = `
import { foo as foo1 } from 'module1';
import { foo as foo2 } from 'module2';
// check that queryObjects works with JSModuleNamespace
import * as foo3 from 'module2';
console.log(foo1());
console.log(foo2());
import { a1 } from 'module1';
import { a2 } from 'module2';
debugger;
foo3;
`;
var module4 = '}';
(async function test() {
session.setupScriptMap();
// We get scriptParsed events for modules ..
Protocol.Debugger.onScriptParsed(InspectorTest.logMessage);
// .. scriptFailed to parse for modules with syntax error ..
Protocol.Debugger.onScriptFailedToParse(InspectorTest.logMessage);
// .. API messages from modules contain correct stack trace ..
Protocol.Runtime.onConsoleAPICalled(message => {
InspectorTest.log(`console.log(${message.params.args[0].value})`);
session.logCallFrames(message.params.stackTrace.callFrames);
InspectorTest.log('');
});
// .. we could break inside module and scope contains correct list of variables ..
Protocol.Debugger.onPaused(message => {
InspectorTest.logMessage(message);
Protocol.Runtime.getProperties({ objectId: message.params.callFrames[0].scopeChain[0].object.objectId})
.then(InspectorTest.logMessage)
.then(() => Protocol.Debugger.resume());
});
// .. we process uncaught errors from modules correctly.
Protocol.Runtime.onExceptionThrown(InspectorTest.logMessage);
Protocol.Runtime.enable();
await Protocol.Debugger.enable();
await contextGroup.addModule(module1, 'module1');
await contextGroup.addModule(module2, 'module2');
await contextGroup.addModule(module3, 'module3');
await contextGroup.addModule(module4, 'module4');
await InspectorTest.waitForPendingTasks();
Protocol.Debugger.onScriptParsed(null);
Protocol.Runtime.evaluate({
includeCommandLineAPI: true,
expression: 'queryObjects(Function)'
});
const {params:{object:{objectId}}} = await Protocol.Runtime.onceInspectRequested();
const {result:{objects}} = await Protocol.Runtime.queryObjects({
prototypeObjectId: objectId
});
InspectorTest.log('queryObjects returns ' + objects.description.replace(/\d+/, 'N'));
InspectorTest.completeTest();
})();

View File

@ -0,0 +1,249 @@
Tests that Runtime.evaluate works with awaitPromise flag.
Running test: testResolvedPromise
{
id : <messageId>
result : {
result : {
description : 239
type : number
value : 239
}
}
}
Running test: testRejectedPromise
{
id : <messageId>
result : {
exceptionDetails : {
columnNumber : 0
exception : {
description : 239
type : number
value : 239
}
exceptionId : <exceptionId>
lineNumber : 0
text : Uncaught (in promise)
}
result : {
description : 239
type : number
value : 239
}
}
}
Running test: testRejectedPromiseWithError
{
id : <messageId>
result : {
exceptionDetails : {
columnNumber : 11
exception : {
className : Error
description : Error: MyError at foo (<anonymous>:13:11) at throwError (<anonymous>:15:3)
objectId : <objectId>
subtype : error
type : object
}
exceptionId : <exceptionId>
lineNumber : 13
scriptId : <scriptId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 10
functionName : foo
lineNumber : 12
scriptId : <scriptId>
url :
}
[1] : {
columnNumber : 2
functionName : throwError
lineNumber : 14
scriptId : <scriptId>
url :
}
]
}
text : Uncaught (in promise) Error: MyError
}
result : {
className : Error
description : Error: MyError at foo (<anonymous>:13:11) at throwError (<anonymous>:15:3)
objectId : <objectId>
subtype : error
type : object
}
}
}
Running test: testRejectedPromiseWithSyntaxError
{
id : <messageId>
result : {
exceptionDetails : {
columnNumber : 5
exception : {
className : SyntaxError
description : SyntaxError: Unexpected token '}' at foo (<anonymous>:21:5) at throwSyntaxError (<anonymous>:23:3)
objectId : <objectId>
subtype : error
type : object
}
exceptionId : <exceptionId>
lineNumber : 21
scriptId : <scriptId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 4
functionName : foo
lineNumber : 20
scriptId : <scriptId>
url :
}
[1] : {
columnNumber : 2
functionName : throwSyntaxError
lineNumber : 22
scriptId : <scriptId>
url :
}
]
}
text : Uncaught (in promise) SyntaxError: Unexpected token '}'
}
result : {
className : SyntaxError
description : SyntaxError: Unexpected token '}' at foo (<anonymous>:21:5) at throwSyntaxError (<anonymous>:23:3)
objectId : <objectId>
subtype : error
type : object
}
}
}
Running test: testPrimitiveValueInsteadOfPromise
{
id : <messageId>
result : {
result : {
type : boolean
value : true
}
}
}
Running test: testObjectInsteadOfPromise
{
id : <messageId>
result : {
result : {
type : object
value : {
}
}
}
}
Running test: testPendingPromise
{
id : <messageId>
result : {
result : {
type : object
value : {
a : 239
}
}
}
}
Running test: testExceptionInEvaluate
{
id : <messageId>
result : {
exceptionDetails : {
columnNumber : 0
exception : {
description : 239
type : number
value : 239
}
exceptionId : <exceptionId>
lineNumber : 0
scriptId : <scriptId>
text : Uncaught
}
result : {
description : 239
type : number
value : 239
}
}
}
Running test: testThenableJob
{
id : <messageId>
result : {
result : {
description : 42
type : number
value : 42
}
}
}
Running test: testLastEvaluatedResult
{
id : <messageId>
result : {
result : {
description : 42
type : number
value : 42
}
}
}
{
id : <messageId>
result : {
result : {
description : 42
type : number
value : 42
}
}
}
Running test: testRuntimeDisable
Resolving promise..
{
id : <messageId>
result : {
result : {
className : Object
description : Object
objectId : <objectId>
type : object
}
}
}
Promise resolved
Running test: testImmediatelyResolvedAfterAfterContextDestroyed
Destroying context..
{
error : {
code : -32000
message : Execution context was destroyed.
}
id : <messageId>
}
Context destroyed
Triggering weak callback..

View File

@ -0,0 +1,8 @@
Test that Runtime.evaluate correctly process errors during wrapping async result.
{
error : {
code : -32000
message : Object couldn't be returned by value
}
id : <messageId>
}

View File

@ -0,0 +1,15 @@
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
let {session, contextGroup, Protocol} = InspectorTest.start("Test that " +
"Runtime.evaluate correctly process errors during wrapping async result.");
var evaluateArguments = {
expression: "Promise.resolve(Symbol(123))",
returnByValue: true,
awaitPromise: true
};
Protocol.Runtime.evaluate(evaluateArguments)
.then(message => InspectorTest.logMessage(message))
.then(() => InspectorTest.completeTest());

View File

@ -0,0 +1,150 @@
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --no-stress-incremental-marking
let {session, contextGroup, Protocol} = InspectorTest.start("Tests that Runtime.evaluate works with awaitPromise flag.");
contextGroup.addScript(`
function createPromiseAndScheduleResolve()
{
var resolveCallback;
var promise = new Promise((resolve) => resolveCallback = resolve);
setTimeout(resolveCallback.bind(null, { a : 239 }), 0);
return promise;
}
function throwError()
{
function foo() {
throw new Error('MyError');
}
foo();
}
function throwSyntaxError()
{
function foo() {
eval('}');
}
foo();
}
`);
InspectorTest.runAsyncTestSuite([
async function testResolvedPromise()
{
InspectorTest.logMessage(await Protocol.Runtime.evaluate({
expression: "Promise.resolve(239)",
awaitPromise: true,
generatePreview: true
}));
},
async function testRejectedPromise()
{
InspectorTest.logMessage(await Protocol.Runtime.evaluate({
expression: "Promise.reject(239)",
awaitPromise: true
}));
},
async function testRejectedPromiseWithError()
{
Protocol.Runtime.enable();
InspectorTest.logMessage(await Protocol.Runtime.evaluate({
expression: "Promise.resolve().then(throwError)",
awaitPromise: true
}));
await Protocol.Runtime.disable();
},
async function testRejectedPromiseWithSyntaxError()
{
Protocol.Runtime.enable();
InspectorTest.logMessage(await Protocol.Runtime.evaluate({
expression: "Promise.resolve().then(throwSyntaxError)",
awaitPromise: true
}));
await Protocol.Runtime.disable();
},
async function testPrimitiveValueInsteadOfPromise()
{
InspectorTest.logMessage(await Protocol.Runtime.evaluate({
expression: "true",
awaitPromise: true
}));
},
async function testObjectInsteadOfPromise()
{
InspectorTest.logMessage(await Protocol.Runtime.evaluate({
expression: "({})",
awaitPromise: true,
returnByValue: true
}));
},
async function testPendingPromise()
{
InspectorTest.logMessage(await Protocol.Runtime.evaluate({
expression: "createPromiseAndScheduleResolve()",
awaitPromise: true,
returnByValue: true
}));
},
async function testExceptionInEvaluate()
{
InspectorTest.logMessage(await Protocol.Runtime.evaluate({
expression: "throw 239",
awaitPromise: true
}));
},
async function testThenableJob()
{
InspectorTest.logMessage(await Protocol.Runtime.evaluate({
expression: '({then: resolve => resolve(42)})',
awaitPromise: true}));
},
async function testLastEvaluatedResult()
{
InspectorTest.logMessage(await Protocol.Runtime.evaluate({
expression: 'Promise.resolve(42)',
awaitPromise: true,
objectGroup: 'console'
}));
InspectorTest.logMessage(await Protocol.Runtime.evaluate({
expression: '$_',
includeCommandLineAPI: true
}));
},
async function testRuntimeDisable()
{
await Protocol.Runtime.enable();
Protocol.Runtime.evaluate({
expression: 'new Promise(r1 => r = r1)',
awaitPromise: true }).then(InspectorTest.logMessage);
await Protocol.Runtime.disable();
InspectorTest.log('Resolving promise..');
await Protocol.Runtime.evaluate({expression: 'r({a:1})'});
InspectorTest.log('Promise resolved');
},
async function testImmediatelyResolvedAfterAfterContextDestroyed()
{
Protocol.Runtime.evaluate({
expression: 'new Promise(() => 42)',
awaitPromise: true }).then(InspectorTest.logMessage);
InspectorTest.log('Destroying context..');
await Protocol.Runtime.evaluate({expression: 'inspector.fireContextDestroyed()'});
InspectorTest.log('Context destroyed');
InspectorTest.log('Triggering weak callback..');
await Protocol.HeapProfiler.collectGarbage();
}
]);

View File

@ -0,0 +1,10 @@
Tests that Runtime.evaluate works with an empty stack
{
id : <messageId>
result : {
result : {
type : string
value : snape kills dumbledore
}
}
}

View File

@ -0,0 +1,13 @@
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
let {session, contextGroup, Protocol} = InspectorTest.start("Tests that Runtime.evaluate works with an empty stack");
contextGroup.addScript("var text = [48116210, 34460128, 1406661984071834]");
var message = { expression: "text.map(x => x.toString(36)).join(' ')" };
Protocol.Runtime.evaluate(message)
.then(message => InspectorTest.logMessage(message))
.then(() => InspectorTest.completeTest());

View File

@ -0,0 +1,27 @@
Tests that Runtime.evaluate has the correct error line number for 'new Function(...)'
{
id : <messageId>
result : {
exceptionDetails : {
columnNumber : 3
exception : {
className : TypeError
description : TypeError: 0 is not a function at eval (eval at <anonymous> (:1:1), <anonymous>:3:4) at <anonymous>:1:22
objectId : <objectId>
subtype : error
type : object
}
exceptionId : <exceptionId>
lineNumber : 2
scriptId : <scriptId>
text : Uncaught
}
result : {
className : TypeError
description : TypeError: 0 is not a function at eval (eval at <anonymous> (:1:1), <anonymous>:3:4) at <anonymous>:1:22
objectId : <objectId>
subtype : error
type : object
}
}
}

View File

@ -0,0 +1,11 @@
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
let {session, contextGroup, Protocol} = InspectorTest.start("Tests that Runtime.evaluate has the correct error line number for 'new Function(...)'");
var message = { expression: "new Function('(0)()')();" };
Protocol.Runtime.evaluate(message)
.then(message => InspectorTest.logMessage(message))
.then(() => InspectorTest.completeTest());

View File

@ -0,0 +1,55 @@
Evaluate conflicting private class member out of class scope in Runtime.evaluate()
class Klass {
#name = "string";
}
class ClassWithField extends Klass {
#name = "child";
}
class ClassWithMethod extends Klass {
#name() {}
}
class ClassWithAccessor extends Klass {
get #name() {}
set #name(val) {}
}
class StaticClass extends Klass {
static #name = "child";
}
Running test: evaluatePrivateMembers
Runtime.evaluate: `(new ClassWithField).#name`
{
className : Error
description : Error: Operation is ambiguous because there are more than one private name'#name' on the object at <anonymous>:1:2
objectId : <objectId>
subtype : error
type : object
}
Runtime.evaluate: `(new ClassWithMethod).#name`
{
className : Error
description : Error: Operation is ambiguous because there are more than one private name'#name' on the object at <anonymous>:1:2
objectId : <objectId>
subtype : error
type : object
}
Runtime.evaluate: `(new ClassWithAccessor).#name`
{
className : Error
description : Error: Operation is ambiguous because there are more than one private name'#name' on the object at <anonymous>:1:2
objectId : <objectId>
subtype : error
type : object
}
Runtime.evaluate: `StaticClass.#name`
{
type : string
value : child
}
Runtime.evaluate: `(new StaticClass).#name`
{
type : string
value : string
}

View File

@ -0,0 +1,12 @@
// Copyright 2022 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
utils.load('test/inspector/private-class-member-inspector-test.js');
const options = {
type: 'private-conflicting-member',
testRuntime: true,
message: `Evaluate conflicting private class member out of class scope in Runtime.evaluate()`
};
PrivateClassMemberInspectorTest.runTest(InspectorTest, options);

View File

@ -0,0 +1,231 @@
Evaluate private class member out of class scope in Runtime.evaluate()
class Klass {
#field = "string";
get #getterOnly() { return "getterOnly"; }
set #setterOnly(val) { this.#field = "setterOnlyCalled"; }
get #accessor() { return this.#field }
set #accessor(val) { this.#field = val; }
#method() { return "method"; }
}
const obj = new Klass();
Running test: evaluatePrivateMembers
Checking private fields
Runtime.evaluate: `obj.#field`
{
type : string
value : string
}
Runtime.evaluate: `obj.#field = 1`
{
description : 1
type : number
value : 1
}
Runtime.evaluate: `obj.#field`
{
description : 1
type : number
value : 1
}
Runtime.evaluate: `obj.#field++`
{
description : 1
type : number
value : 1
}
Runtime.evaluate: `obj.#field`
{
description : 2
type : number
value : 2
}
Runtime.evaluate: `++obj.#field`
{
description : 3
type : number
value : 3
}
Runtime.evaluate: `obj.#field`
{
description : 3
type : number
value : 3
}
Runtime.evaluate: `obj.#field -= 3`
{
description : 0
type : number
value : 0
}
Runtime.evaluate: `obj.#field`
{
description : 0
type : number
value : 0
}
Checking private getter-only accessors
Runtime.evaluate: `obj.#getterOnly`
{
type : string
value : getterOnly
}
Runtime.evaluate: `obj.#getterOnly = 1`
{
className : Error
description : Error: '#getterOnly' was defined without a setter at <anonymous>:1:17
objectId : <objectId>
subtype : error
type : object
}
Runtime.evaluate: `obj.#getterOnly++`
{
className : Error
description : Error: '#getterOnly' was defined without a setter at <anonymous>:1:16
objectId : <objectId>
subtype : error
type : object
}
Runtime.evaluate: `obj.#getterOnly -= 3`
{
className : Error
description : Error: '#getterOnly' was defined without a setter at <anonymous>:1:17
objectId : <objectId>
subtype : error
type : object
}
Runtime.evaluate: `obj.#getterOnly`
{
type : string
value : getterOnly
}
Checking private setter-only accessors
Runtime.evaluate: `obj.#setterOnly`
{
className : Error
description : Error: '#setterOnly' was defined without a getter at <anonymous>:1:1
objectId : <objectId>
subtype : error
type : object
}
Runtime.evaluate: `obj.#setterOnly = 1`
{
description : 1
type : number
value : 1
}
Runtime.evaluate: `obj.#setterOnly++`
{
className : Error
description : Error: '#setterOnly' was defined without a getter at <anonymous>:1:1
objectId : <objectId>
subtype : error
type : object
}
Runtime.evaluate: `obj.#setterOnly -= 3`
{
className : Error
description : Error: '#setterOnly' was defined without a getter at <anonymous>:1:1
objectId : <objectId>
subtype : error
type : object
}
Runtime.evaluate: `obj.#field`
{
type : string
value : setterOnlyCalled
}
Checking private accessors
Runtime.evaluate: `obj.#accessor`
{
type : string
value : setterOnlyCalled
}
Runtime.evaluate: `obj.#accessor = 1`
{
description : 1
type : number
value : 1
}
Runtime.evaluate: `obj.#field`
{
description : 1
type : number
value : 1
}
Runtime.evaluate: `obj.#accessor++`
{
description : 1
type : number
value : 1
}
Runtime.evaluate: `obj.#field`
{
description : 2
type : number
value : 2
}
Runtime.evaluate: `++obj.#accessor`
{
type : undefined
}
Runtime.evaluate: `obj.#field`
{
description : 3
type : number
value : 3
}
Runtime.evaluate: `obj.#accessor -= 3`
{
description : 0
type : number
value : 0
}
Runtime.evaluate: `obj.#field`
{
description : 0
type : number
value : 0
}
Checking private methods
Runtime.evaluate: `obj.#method`
{
className : Function
description : #method() { return "method"; }
objectId : <objectId>
type : function
}
Runtime.evaluate: `obj.#method = 1`
{
className : Error
description : Error: Private method '#method' is not writable at <anonymous>:1:13
objectId : <objectId>
subtype : error
type : object
}
Runtime.evaluate: `obj.#method++`
{
className : Error
description : Error: Private method '#method' is not writable at <anonymous>:1:12
objectId : <objectId>
subtype : error
type : object
}
Runtime.evaluate: `++obj.#method`
{
className : Error
description : Error: Private method '#method' is not writable at <anonymous>:1:7
objectId : <objectId>
subtype : error
type : object
}
Runtime.evaluate: `obj.#method -= 3`
{
className : Error
description : Error: Private method '#method' is not writable at <anonymous>:1:13
objectId : <objectId>
subtype : error
type : object
}

View File

@ -0,0 +1,99 @@
Evaluate getting private member from Smi
Running test: evaluatePrivateMember
Debugger.evaluateOnCallFrame: `(1).#test = 1`
{
className : TypeError
description : TypeError: Cannot access private name #test from 1 at eval (eval at <anonymous> (:1:1), <anonymous>:1:11) at <anonymous>:1:1
objectId : <objectId>
subtype : error
type : object
}
Debugger.evaluateOnCallFrame: `(1).#test`
{
className : TypeError
description : TypeError: Cannot access private name #test from 1 at eval (eval at <anonymous> (:1:1), <anonymous>:1:1) at <anonymous>:1:1
objectId : <objectId>
subtype : error
type : object
}
Debugger.evaluateOnCallFrame: `(null).#test = 1`
{
className : TypeError
description : TypeError: Cannot access private name #test from null at eval (eval at <anonymous> (:1:1), <anonymous>:1:14) at <anonymous>:1:1
objectId : <objectId>
subtype : error
type : object
}
Debugger.evaluateOnCallFrame: `(null).#test`
{
className : TypeError
description : TypeError: Cannot access private name #test from null at eval (eval at <anonymous> (:1:1), <anonymous>:1:1) at <anonymous>:1:1
objectId : <objectId>
subtype : error
type : object
}
Debugger.evaluateOnCallFrame: `(undefined).#test = 1`
{
className : TypeError
description : TypeError: Cannot access private name #test from undefined at eval (eval at <anonymous> (:1:1), <anonymous>:1:19) at <anonymous>:1:1
objectId : <objectId>
subtype : error
type : object
}
Debugger.evaluateOnCallFrame: `(undefined).#test`
{
className : TypeError
description : TypeError: Cannot access private name #test from undefined at eval (eval at <anonymous> (:1:1), <anonymous>:1:1) at <anonymous>:1:1
objectId : <objectId>
subtype : error
type : object
}
Debugger.evaluateOnCallFrame: `(true).#test = 1`
{
className : TypeError
description : TypeError: Cannot access private name #test from true at eval (eval at <anonymous> (:1:1), <anonymous>:1:14) at <anonymous>:1:1
objectId : <objectId>
subtype : error
type : object
}
Debugger.evaluateOnCallFrame: `(true).#test`
{
className : TypeError
description : TypeError: Cannot access private name #test from true at eval (eval at <anonymous> (:1:1), <anonymous>:1:1) at <anonymous>:1:1
objectId : <objectId>
subtype : error
type : object
}
Debugger.evaluateOnCallFrame: `("str").#test = 1`
{
className : TypeError
description : TypeError: Cannot access private name #test from str at eval (eval at <anonymous> (:1:1), <anonymous>:1:15) at <anonymous>:1:1
objectId : <objectId>
subtype : error
type : object
}
Debugger.evaluateOnCallFrame: `("str").#test`
{
className : TypeError
description : TypeError: Cannot access private name #test from str at eval (eval at <anonymous> (:1:1), <anonymous>:1:1) at <anonymous>:1:1
objectId : <objectId>
subtype : error
type : object
}
Debugger.evaluateOnCallFrame: `Symbol("str").#test = 1`
{
className : TypeError
description : TypeError: Cannot access private name #test from Symbol(str) at eval (eval at <anonymous> (:1:1), <anonymous>:1:21) at <anonymous>:1:1
objectId : <objectId>
subtype : error
type : object
}
Debugger.evaluateOnCallFrame: `Symbol("str").#test`
{
className : TypeError
description : TypeError: Cannot access private name #test from Symbol(str) at eval (eval at <anonymous> (:1:1), <anonymous>:1:1) at <anonymous>:1:1
objectId : <objectId>
subtype : error
type : object
}

View File

@ -0,0 +1,41 @@
// Copyright 2025 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
const { contextGroup, Protocol } = InspectorTest.start(`Evaluate getting private member from Smi`);
async function runAndLog(expression) {
Protocol.Runtime.evaluate({expression: 'debugger;'});
const { params: { callFrames } } = await Protocol.Debugger.oncePaused();
const frame = callFrames[0];
InspectorTest.log(`Debugger.evaluateOnCallFrame: \`${expression}\``);
const { result: { result } } =
await Protocol.Debugger.evaluateOnCallFrame({
callFrameId: frame.callFrameId,
expression
});
InspectorTest.logMessage(result);
Protocol.Debugger.resume();
}
InspectorTest.runAsyncTestSuite([
async function evaluatePrivateMember() {
Protocol.Debugger.enable();
Protocol.Runtime.enable();
await runAndLog('(1).#test = 1');
await runAndLog('(1).#test');
await runAndLog('(null).#test = 1');
await runAndLog('(null).#test');
await runAndLog('(undefined).#test = 1');
await runAndLog('(undefined).#test');
await runAndLog('(true).#test = 1');
await runAndLog('(true).#test');
await runAndLog('("str").#test = 1');
await runAndLog('("str").#test');
await runAndLog('Symbol("str").#test = 1');
await runAndLog('Symbol("str").#test');
InspectorTest.completeTest();
}]
);

View File

@ -0,0 +1,231 @@
Evaluate static private class member out of class scope in Runtime.evaluate()
class Klass {
static #field = "string";
static get #getterOnly() { return "getterOnly"; }
static set #setterOnly(val) { this.#field = "setterOnlyCalled"; }
static get #accessor() { return this.#field }
static set #accessor(val) { this.#field = val; }
static #method() { return "method"; }
}
const obj = new Klass();
Running test: evaluatePrivateMembers
Checking private fields
Runtime.evaluate: `Klass.#field`
{
type : string
value : string
}
Runtime.evaluate: `Klass.#field = 1`
{
description : 1
type : number
value : 1
}
Runtime.evaluate: `Klass.#field`
{
description : 1
type : number
value : 1
}
Runtime.evaluate: `Klass.#field++`
{
description : 1
type : number
value : 1
}
Runtime.evaluate: `Klass.#field`
{
description : 2
type : number
value : 2
}
Runtime.evaluate: `++Klass.#field`
{
description : 3
type : number
value : 3
}
Runtime.evaluate: `Klass.#field`
{
description : 3
type : number
value : 3
}
Runtime.evaluate: `Klass.#field -= 3`
{
description : 0
type : number
value : 0
}
Runtime.evaluate: `Klass.#field`
{
description : 0
type : number
value : 0
}
Checking private getter-only accessors
Runtime.evaluate: `Klass.#getterOnly`
{
type : string
value : getterOnly
}
Runtime.evaluate: `Klass.#getterOnly = 1`
{
className : Error
description : Error: '#getterOnly' was defined without a setter at <anonymous>:1:19
objectId : <objectId>
subtype : error
type : object
}
Runtime.evaluate: `Klass.#getterOnly++`
{
className : Error
description : Error: '#getterOnly' was defined without a setter at <anonymous>:1:18
objectId : <objectId>
subtype : error
type : object
}
Runtime.evaluate: `Klass.#getterOnly -= 3`
{
className : Error
description : Error: '#getterOnly' was defined without a setter at <anonymous>:1:19
objectId : <objectId>
subtype : error
type : object
}
Runtime.evaluate: `Klass.#getterOnly`
{
type : string
value : getterOnly
}
Checking private setter-only accessors
Runtime.evaluate: `Klass.#setterOnly`
{
className : Error
description : Error: '#setterOnly' was defined without a getter at <anonymous>:1:1
objectId : <objectId>
subtype : error
type : object
}
Runtime.evaluate: `Klass.#setterOnly = 1`
{
description : 1
type : number
value : 1
}
Runtime.evaluate: `Klass.#setterOnly++`
{
className : Error
description : Error: '#setterOnly' was defined without a getter at <anonymous>:1:1
objectId : <objectId>
subtype : error
type : object
}
Runtime.evaluate: `Klass.#setterOnly -= 3`
{
className : Error
description : Error: '#setterOnly' was defined without a getter at <anonymous>:1:1
objectId : <objectId>
subtype : error
type : object
}
Runtime.evaluate: `Klass.#field`
{
type : string
value : setterOnlyCalled
}
Checking private accessors
Runtime.evaluate: `Klass.#accessor`
{
type : string
value : setterOnlyCalled
}
Runtime.evaluate: `Klass.#accessor = 1`
{
description : 1
type : number
value : 1
}
Runtime.evaluate: `Klass.#field`
{
description : 1
type : number
value : 1
}
Runtime.evaluate: `Klass.#accessor++`
{
description : 1
type : number
value : 1
}
Runtime.evaluate: `Klass.#field`
{
description : 2
type : number
value : 2
}
Runtime.evaluate: `++Klass.#accessor`
{
type : undefined
}
Runtime.evaluate: `Klass.#field`
{
description : 3
type : number
value : 3
}
Runtime.evaluate: `Klass.#accessor -= 3`
{
description : 0
type : number
value : 0
}
Runtime.evaluate: `Klass.#field`
{
description : 0
type : number
value : 0
}
Checking private methods
Runtime.evaluate: `Klass.#method`
{
className : Function
description : #method() { return "method"; }
objectId : <objectId>
type : function
}
Runtime.evaluate: `Klass.#method = 1`
{
className : Error
description : Error: Private method '#method' is not writable at <anonymous>:1:15
objectId : <objectId>
subtype : error
type : object
}
Runtime.evaluate: `Klass.#method++`
{
className : Error
description : Error: Private method '#method' is not writable at <anonymous>:1:14
objectId : <objectId>
subtype : error
type : object
}
Runtime.evaluate: `++Klass.#method`
{
className : Error
description : Error: Private method '#method' is not writable at <anonymous>:1:9
objectId : <objectId>
subtype : error
type : object
}
Runtime.evaluate: `Klass.#method -= 3`
{
className : Error
description : Error: Private method '#method' is not writable at <anonymous>:1:15
objectId : <objectId>
subtype : error
type : object
}

View File

@ -0,0 +1,12 @@
// Copyright 2022 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
utils.load('test/inspector/private-class-member-inspector-test.js');
const options = {
type: 'private-static-member',
testRuntime: true,
message: `Evaluate static private class member out of class scope in Runtime.evaluate()`
};
PrivateClassMemberInspectorTest.runTest(InspectorTest, options);

View File

@ -0,0 +1,12 @@
// Copyright 2022 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
utils.load('test/inspector/private-class-member-inspector-test.js');
const options = {
type: 'private-instance-member',
testRuntime: true,
message: `Evaluate private class member out of class scope in Runtime.evaluate()`
};
PrivateClassMemberInspectorTest.runTest(InspectorTest, options);

View File

@ -0,0 +1,81 @@
Tests that top-level await in Runtime.evaluate REPL mode includes stack trace.
{
id : <messageId>
result : {
exceptionDetails : {
columnNumber : 0
exception : {
type : undefined
}
exceptionId : <exceptionId>
lineNumber : 0
scriptId : <scriptId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 0
functionName :
lineNumber : 0
scriptId : <scriptId>
url :
}
]
}
text : Uncaught
}
result : {
type : undefined
}
}
}
{
id : <messageId>
result : {
exceptionDetails : {
columnNumber : 6
exception : {
className : Error
description : Error: ba dum tsh at bar (<anonymous>:3:13) at foo (<anonymous>:7:7) at <anonymous>:10:5
objectId : <objectId>
subtype : error
type : object
}
exceptionId : <exceptionId>
lineNumber : 2
scriptId : <scriptId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 12
functionName : bar
lineNumber : 2
scriptId : <scriptId>
url :
}
[1] : {
columnNumber : 6
functionName : foo
lineNumber : 6
scriptId : <scriptId>
url :
}
[2] : {
columnNumber : 4
functionName :
lineNumber : 9
scriptId : <scriptId>
url :
}
]
}
text : Uncaught
}
result : {
className : Error
description : Error: ba dum tsh at bar (<anonymous>:3:13) at foo (<anonymous>:7:7) at <anonymous>:10:5
objectId : <objectId>
subtype : error
type : object
}
}
}

View File

@ -0,0 +1,34 @@
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
let {Protocol} = InspectorTest.start(
"Tests that top-level await in Runtime.evaluate REPL mode includes stack trace.");
Protocol.Debugger.enable();
Protocol.Runtime.enable();
(async function() {
evaluateRepl('throw undefined;');
evaluateRepl(`
function bar() {
throw new Error('ba dum tsh');
}
function foo() {
bar();
}
foo();
`);
InspectorTest.completeTest();
})();
async function evaluateRepl(expression) {
InspectorTest.logMessage(await Protocol.Runtime.evaluate({
expression: expression,
replMode: true,
}));
}

View File

@ -0,0 +1,6 @@
Tests that REPL mode still works even with a broken Promise.prototype.then
{
description : 42
type : number
value : 42
}

View File

@ -0,0 +1,20 @@
// Copyright 2022 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
const {contextGroup, Protocol} = InspectorTest.start(
"Tests that REPL mode still works even with a broken Promise.prototype.then");
(async function() {
contextGroup.addScript(`
Promise.prototype.then = () => {throw Error('you shall not evaluate')};
`);
const { result: { result }} = await Protocol.Runtime.evaluate({
expression: '42',
replMode: true,
});
InspectorTest.logMessage(result);
InspectorTest.completeTest();
})();

Some files were not shown because too many files have changed in this diff Show More