Commit ee0d6991 authored by machenbach's avatar machenbach Committed by Commit bot

Revert "[inspector] added inspector test runner [part 3-5]"

Revert "[inspector] added inspector test runner [part 3]"

This reverts commit f3f9f444.

Revert "[inspector] added inspector test runner [part 4]"

This reverts commit 4a5f5d09.

Revert "[inspector] added inspector test runner [part 5]"

This reverts commit 9ddbdab1.

Reverting this in order to revert parts 1-2 which block the roll:
https://codereview.chromium.org/2379053003/

BUG=chromium:635948
TBR=kozyatinskiy@chromium.org,
NOTRY=true

Review-Url: https://codereview.chromium.org/2379303002
Cr-Commit-Position: refs/heads/master@{#39908}
parent 772ea905
......@@ -10,7 +10,6 @@ v8_executable("inspector-test") {
sources = [
"inspector-impl.cc",
"inspector-impl.h",
"inspector-test.cc",
"task-runner.cc",
"task-runner.h",
]
......
......@@ -2,9 +2,6 @@ include_rules = [
"-src",
"+src/base/macros.h",
"+src/base/platform/platform.h",
"+src/flags.h",
"+src/inspector/string-16.h",
"+src/locked-queue-inl.h",
"+src/utils.h",
"+src/vector.h",
]
\ No newline at end of file
first "let a = 1;" result: wasThrown = false
second "let a = 1;" result: wasThrown = true
exception message: Uncaught SyntaxError: Identifier 'a' has already been declared
at <anonymous>:1:1
{"result":{"type":"number","value":42,"description":"42"}}
function dir(value) { [Command Line API] }
function dirxml(value) { [Command Line API] }
function keys(object) { [Command Line API] }
function values(object) { [Command Line API] }
function profile(title) { [Command Line API] }
function profileEnd(title) { [Command Line API] }
function inspect(object) { [Command Line API] }
function copy(value) { [Command Line API] }
function clear() { [Command Line API] }
function debug(function) { [Command Line API] }
function undebug(function) { [Command Line API] }
function monitor(function) { [Command Line API] }
function unmonitor(function) { [Command Line API] }
function table(data, [columns]) { [Command Line API] }
\ No newline at end of file
// 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.
InspectorTest.sendCommand("Runtime.evaluate", { expression: "let a = 42;" }, step2);
function step2(response)
{
failIfError(response);
InspectorTest.log("first \"let a = 1;\" result: wasThrown = " + !!response.result.exceptionDetails);
InspectorTest.sendCommand("Runtime.evaluate", { expression: "let a = 239;" }, step3);
}
function step3(response)
{
failIfError(response);
InspectorTest.log("second \"let a = 1;\" result: wasThrown = " + !!response.result.exceptionDetails);
if (response.result.exceptionDetails)
InspectorTest.log("exception message: " + response.result.exceptionDetails.text + " " + response.result.exceptionDetails.exception.description);
InspectorTest.sendCommand("Runtime.evaluate", { expression: "a" }, step4);
}
function step4(response)
{
failIfError(response);
InspectorTest.log(JSON.stringify(response.result));
checkMethod(null);
}
var methods = [ "dir", "dirxml", "keys", "values", "profile", "profileEnd",
"inspect", "copy", "clear",
"debug", "undebug", "monitor", "unmonitor", "table" ];
function checkMethod(response)
{
failIfError(response);
if (response)
InspectorTest.log(response.result.result.description);
var method = methods.shift();
if (!method)
InspectorTest.completeTest();
InspectorTest.sendCommand("Runtime.evaluate", { expression: method, includeCommandLineAPI: true }, checkMethod);
}
function failIfError(response)
{
if (response && response.error)
InspectorTest.log("FAIL: " + JSON.stringify(response.error));
}
Tests checks that console.memory property can be set in strict mode (crbug.com/468611).
{
id : 0
result : {
result : {
type : undefined
}
}
}
\ No newline at end of file
// 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.
print("Tests checks that console.memory property can be set in strict mode (crbug.com/468611).")
InspectorTest.sendCommand("Runtime.evaluate", { expression: "\"use strict\"\nconsole.memory = {};undefined" }, dumpResult);
function dumpResult(result)
{
result.id = 0;
InspectorTest.logObject(result);
InspectorTest.completeTest();
}
Tests that "console.profileEnd()" does not cause crash. (webkit:105759)
SUCCESS: found 2 profile headers
SUCCESS: titled profile found
\ No newline at end of file
// 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.
print("Tests that \"console.profileEnd()\" does not cause crash. (webkit:105759)");
InspectorTest.evaluateInPage(`
function collectProfiles()
{
console.profile();
console.profile("titled");
console.profileEnd();
console.profileEnd();
}`);
InspectorTest.fail = function(message)
{
InspectorTest.log("FAIL: " + message);
InspectorTest.completeTest();
}
InspectorTest.sendCommand("Profiler.enable", {});
InspectorTest.sendCommand("Runtime.evaluate", { expression: "collectProfiles()"}, didCollectProfiles);
var headers = [];
InspectorTest.eventHandler["Profiler.consoleProfileFinished"] = function(messageObject)
{
headers.push({
title: messageObject["params"]["title"]
});
}
function didCollectProfiles(messageObject)
{
if (headers.length !== 2)
return InspectorTest.fail("Cannot retrive headers: " + JSON.stringify(messageObject, null, 4));
InspectorTest.log("SUCCESS: found 2 profile headers");
for (var i = 0; i < headers.length; i++) {
if (headers[i].title === "titled") {
InspectorTest.log("SUCCESS: titled profile found");
InspectorTest.completeTest();
return;
}
}
InspectorTest.fail("Cannot find titled profile");
}
Tests that console.profile/profileEnd will record CPU profile when inspector front-end is connected.
SUCCESS: retrieved '42' profile
SUCCESS: found 'collectProfiles' function in the profile
\ No newline at end of file
// 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.
print("Tests that console.profile/profileEnd will record CPU profile when inspector front-end is connected.");
InspectorTest.evaluateInPage(`
function collectProfiles()
{
console.profile("outer");
console.profile(42);
console.profileEnd("outer");
console.profileEnd(42);
}`);
InspectorTest.fail = function(message)
{
InspectorTest.log("FAIL: " + message);
InspectorTest.completeTest();
}
InspectorTest.sendCommand("Profiler.enable", {});
InspectorTest.sendCommand("Runtime.evaluate", { expression: "collectProfiles()"}, didCollectProfiles);
var headers = [];
InspectorTest.eventHandler["Profiler.consoleProfileFinished"] = function(messageObject)
{
headers.push({
profile: messageObject["params"]["profile"],
title: messageObject["params"]["title"]
});
}
function didCollectProfiles(messageObject)
{
if (headers.length !== 2)
return InspectorTest.fail("Cannot retrive headers: " + JSON.stringify(messageObject, null, 4));
for (var i = 0; i < headers.length; i++) {
if (headers[i].title === "42") {
checkInnerProfile(headers[i].profile);
return;
}
}
InspectorTest.fail("Cannot find '42' profile header");
}
function checkInnerProfile(profile)
{
InspectorTest.log("SUCCESS: retrieved '42' profile");
if (!findFunctionInProfile(profile.nodes, "collectProfiles"))
return InspectorTest.fail("collectProfiles function not found in the profile: " + JSON.stringify(profile, null, 4));
InspectorTest.log("SUCCESS: found 'collectProfiles' function in the profile");
InspectorTest.completeTest();
}
function findFunctionInProfile(nodes, functionName)
{
return nodes.some(n => n.callFrame.functionName === functionName);
}
Test that profiling can only be started when Profiler was enabled and that Profiler.disable command will stop recording all profiles.
PASS: didFailToStartWhenDisabled
PASS: didStartFrontendProfile
PASS: console initiated profile started
PASS: didStartConsoleProfile
PASS: didDisableProfiler
PASS: no front-end initiated profiles found
PASS: didStopConsoleProfile
\ No newline at end of file
// 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.
print("Test that profiling can only be started when Profiler was enabled and that Profiler.disable command will stop recording all profiles.");
InspectorTest.sendCommand("Profiler.start", {}, didFailToStartWhenDisabled);
disallowConsoleProfiles();
function disallowConsoleProfiles()
{
InspectorTest.eventHandler["Profiler.consoleProfileStarted"] = function(messageObject)
{
InspectorTest.log("FAIL: console profile started " + JSON.stringify(messageObject, null, 4));
}
InspectorTest.eventHandler["Profiler.consoleProfileFinished"] = function(messageObject)
{
InspectorTest.log("FAIL: unexpected profile received " + JSON.stringify(messageObject, null, 4));
}
}
function allowConsoleProfiles()
{
InspectorTest.eventHandler["Profiler.consoleProfileStarted"] = function(messageObject)
{
InspectorTest.log("PASS: console initiated profile started");
}
InspectorTest.eventHandler["Profiler.consoleProfileFinished"] = function(messageObject)
{
InspectorTest.log("PASS: console initiated profile received");
}
}
function didFailToStartWhenDisabled(messageObject)
{
if (!InspectorTest.expectedError("didFailToStartWhenDisabled", messageObject))
return;
allowConsoleProfiles();
InspectorTest.sendCommand("Profiler.enable", {});
InspectorTest.sendCommand("Profiler.start", {}, didStartFrontendProfile);
}
function didStartFrontendProfile(messageObject)
{
if (!InspectorTest.expectedSuccess("didStartFrontendProfile", messageObject))
return;
InspectorTest.sendCommand("Runtime.evaluate", {expression: "console.profile('p1');"}, didStartConsoleProfile);
}
function didStartConsoleProfile(messageObject)
{
if (!InspectorTest.expectedSuccess("didStartConsoleProfile", messageObject))
return;
InspectorTest.sendCommand("Profiler.disable", {}, didDisableProfiler);
}
function didDisableProfiler(messageObject)
{
if (!InspectorTest.expectedSuccess("didDisableProfiler", messageObject))
return;
InspectorTest.sendCommand("Profiler.enable", {});
InspectorTest.sendCommand("Profiler.stop", {}, didStopFrontendProfile);
}
function didStopFrontendProfile(messageObject)
{
if (!InspectorTest.expectedError("no front-end initiated profiles found", messageObject))
return;
disallowConsoleProfiles();
InspectorTest.sendCommand("Runtime.evaluate", {expression: "console.profileEnd();"}, didStopConsoleProfile);
}
function didStopConsoleProfile(messageObject)
{
if (!InspectorTest.expectedSuccess("didStopConsoleProfile", messageObject))
return;
InspectorTest.completeTest();
}
Test that profiler is able to record a profile. Also it tests that profiler returns an error when it unable to find the profile.
PASS: startFrontendProfile
PASS: startConsoleProfile
PASS: stopConsoleProfile
PASS: stoppedFrontendProfile
PASS: startFrontendProfileSecondTime
PASS: stopFrontendProfileSecondTime
\ No newline at end of file
// 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.
print("Test that profiler is able to record a profile. Also it tests that profiler returns an error when it unable to find the profile.");
InspectorTest.sendCommand("Profiler.enable", {});
InspectorTest.sendCommand("Profiler.start", {}, didStartFrontendProfile);
function didStartFrontendProfile(messageObject)
{
if (!InspectorTest.expectedSuccess("startFrontendProfile", messageObject))
return;
InspectorTest.sendCommand("Runtime.evaluate", {expression: "console.profile('Profile 1');"}, didStartConsoleProfile);
}
function didStartConsoleProfile(messageObject)
{
if (!InspectorTest.expectedSuccess("startConsoleProfile", messageObject))
return;
InspectorTest.sendCommand("Runtime.evaluate", {expression: "console.profileEnd('Profile 1');"}, didStopConsoleProfile);
}
function didStopConsoleProfile(messageObject)
{
if (!InspectorTest.expectedSuccess("stopConsoleProfile", messageObject))
return;
InspectorTest.sendCommand("Profiler.stop", {}, didStopFrontendProfile);
}
function didStopFrontendProfile(messageObject)
{
if (!InspectorTest.expectedSuccess("stoppedFrontendProfile", messageObject))
return;
InspectorTest.sendCommand("Profiler.start", {}, didStartFrontendProfile2);
}
function didStartFrontendProfile2(messageObject)
{
if (!InspectorTest.expectedSuccess("startFrontendProfileSecondTime", messageObject))
return;
InspectorTest.sendCommand("Profiler.stop", {}, didStopFrontendProfile2);
}
function didStopFrontendProfile2(messageObject)
{
InspectorTest.expectedSuccess("stopFrontendProfileSecondTime", messageObject)
InspectorTest.completeTest();
}
Test that profiler doesn't crash when we call stop without preceeding start.
PASS: ProfileAgent.stop
\ No newline at end of file
// 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.
print("Test that profiler doesn't crash when we call stop without preceeding start.");
InspectorTest.sendCommand("Profiler.stop", {}, didStopProfile);
function didStopProfile(messageObject)
{
InspectorTest.expectedError("ProfileAgent.stop", messageObject);
InspectorTest.completeTest();
}
Paused on 'debugger;'
resume
restartFrame
PASS, error message as expected
evaluateOnFrame
PASS, error message as expected
setVariableValue
PASS, error message as expected
\ No newline at end of file
// 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.
InspectorTest.evaluateInPage(`
function testFunction()
{
debugger;
}
//# sourceURL=foo.js`);
InspectorTest.sendCommand("Debugger.enable", {});
InspectorTest.eventHandler["Debugger.paused"] = handleDebuggerPausedOne;
InspectorTest.sendCommand("Runtime.evaluate", { "expression": "setTimeout(testFunction, 0)" });
var obsoleteTopFrameId;
function handleDebuggerPausedOne(messageObject)
{
InspectorTest.log("Paused on 'debugger;'");
var topFrame = messageObject.params.callFrames[0];
obsoleteTopFrameId = topFrame.callFrameId;
InspectorTest.eventHandler["Debugger.paused"] = undefined;
InspectorTest.sendCommand("Debugger.resume", { }, callbackResume);
}
function callbackResume(response)
{
InspectorTest.log("resume");
InspectorTest.log("restartFrame");
InspectorTest.sendCommand("Debugger.restartFrame", { callFrameId: obsoleteTopFrameId }, callbackRestartFrame);
}
function callbackRestartFrame(response)
{
logErrorResponse(response);
InspectorTest.log("evaluateOnFrame");
InspectorTest.sendCommand("Debugger.evaluateOnCallFrame", { callFrameId: obsoleteTopFrameId, expression: "0"} , callbackEvaluate);
}
function callbackEvaluate(response)
{
logErrorResponse(response);
InspectorTest.log("setVariableValue");
InspectorTest.sendCommand("Debugger.setVariableValue", { callFrameId: obsoleteTopFrameId, scopeNumber: 0, variableName: "a", newValue: { value: 0 } }, callbackSetVariableValue);
}
function callbackSetVariableValue(response)
{
logErrorResponse(response);
InspectorTest.completeTest();
}
function logErrorResponse(response)
{
if (response.error) {
if (response.error.message.indexOf("Can only perform operation while paused.") !== -1) {
InspectorTest.log("PASS, error message as expected");
return;
}
}
InspectorTest.log("FAIL, unexpected error message");
InspectorTest.log(JSON.stringify(response));
}
Paused on 'debugger;'
Top frame location: {"scriptId":"42","lineNumber":3,"columnNumber":4}
Top frame functionLocation: {"scriptId":"42","lineNumber":0,"columnNumber":21}
// 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.
InspectorTest.evaluateInPage(
`function testFunction()
{
var a = 2;
debugger;
}`);
InspectorTest.sendCommand("Debugger.enable", {});
InspectorTest.eventHandler["Debugger.paused"] = handleDebuggerPaused;
InspectorTest.sendCommand("Runtime.evaluate", { "expression": "setTimeout(testFunction, 0)" });
function handleDebuggerPaused(messageObject)
{
InspectorTest.log("Paused on 'debugger;'");
var topFrame = messageObject.params.callFrames[0];
topFrame.location.scriptId = "42";
topFrame.functionLocation.scriptId = "42";
InspectorTest.log("Top frame location: " + JSON.stringify(topFrame.location));
InspectorTest.log("Top frame functionLocation: " + JSON.stringify(topFrame.functionLocation));
InspectorTest.completeTest();
}
Paused on debugger statement
Paused after continueToLocation
Stopped on line 8, expected 8, requested 8, (0-based numbers).
Control parameter 'step' calculation result: 1, expected: 1
SUCCESS
Paused on debugger statement
Paused after continueToLocation
Stopped on line 8, expected 8, requested 8, (0-based numbers).
Control parameter 'step' calculation result: 1, expected: 1
SUCCESS
Paused on debugger statement
Paused after continueToLocation
Stopped on line 17, expected 17, requested 12, (0-based numbers).
Control parameter 'step' calculation result: 6, expected: 6
SUCCESS
Paused on debugger statement
Paused after continueToLocation
Stopped on line 17, expected 17, requested 13, (0-based numbers).
Control parameter 'step' calculation result: 6, expected: 6
SUCCESS
Paused on debugger statement
Paused after continueToLocation
Stopped on line 17, expected 17, requested 17, (0-based numbers).
Control parameter 'step' calculation result: 6, expected: 6
SUCCESS
Paused on debugger statement
Paused after continueToLocation
Stopped on line 17, expected 17, requested 17, (0-based numbers).
Control parameter 'step' calculation result: 6, expected: 6
SUCCESS
// 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.
InspectorTest.evaluateInPage(
`function statementsExample()
{
var self = arguments.callee;
debugger;
self.step = 1;
self.step = 2;
void [
self.step = 3,
self.step = 4,
self.step = 5,
self.step = 6
];
self.step = 7;
}`);
var scenario = [
// requested line number, expected control parameter 'step', expected line number
[ 8, 1, 8 ],
[ 8, 1, 8 ],
[ 12, 6, 17 ],
[ 13, 6, 17 ],
[ 17, 6, 17 ],
[ 17, 6, 17 ],
];
InspectorTest.sendCommand("Debugger.enable", {});
InspectorTest.sendCommand("Runtime.evaluate", { "expression": "statementsExample" }, callbackEvalFunctionObject);
function callbackEvalFunctionObject(response)
{
var functionObjectId = response.result.result.objectId;
InspectorTest.sendCommand("Runtime.getProperties", { objectId: functionObjectId }, callbackFunctionDetails);
}
function callbackFunctionDetails(response)
{
var result = response.result;
var scriptId;
for (var prop of result.internalProperties) {
if (prop.name === "[[FunctionLocation]]")
scriptId = prop.value.value.scriptId;
}
nextScenarioStep(0);
function nextScenarioStep(pos)
{
if (pos < scenario.length)
gotoSinglePassChain(scriptId, scenario[pos][0], scenario[pos][1], scenario[pos][2], nextScenarioStep.bind(this, pos + 1));
else
InspectorTest.completeTest();
}
}
function gotoSinglePassChain(scriptId, lineNumber, expectedResult, expectedLineNumber, next)
{
InspectorTest.eventHandler["Debugger.paused"] = handleDebuggerPausedOne;
InspectorTest.sendCommand("Runtime.evaluate", { "expression": "setTimeout(statementsExample, 0)" });
function handleDebuggerPausedOne(messageObject)
{
InspectorTest.log("Paused on debugger statement");
InspectorTest.eventHandler["Debugger.paused"] = handleDebuggerPausedTwo;
InspectorTest.sendCommand("Debugger.continueToLocation", { location: { scriptId: scriptId, lineNumber: lineNumber, columnNumber: 0} }, logContinueToLocation);
function logContinueToLocation(response)
{
if (response.error) {
InspectorTest.log("Failed to execute continueToLocation " + JSON.stringify(response.error));
InspectorTest.completeTest();
}
}
}
function handleDebuggerPausedTwo(messageObject)
{
InspectorTest.log("Paused after continueToLocation");
var actualLineNumber = messageObject.params.callFrames[0].location.lineNumber;
InspectorTest.log("Stopped on line " + actualLineNumber + ", expected " + expectedLineNumber + ", requested " + lineNumber + ", (0-based numbers).");
InspectorTest.eventHandler["Debugger.paused"] = handleDebuggerPausedUnexpected;
InspectorTest.sendCommand("Runtime.evaluate", { "expression": "statementsExample.step" }, callbackStepEvaluate);
}
function callbackStepEvaluate(response)
{
var resultValue = response.result.result.value;
InspectorTest.log("Control parameter 'step' calculation result: " + resultValue + ", expected: " + expectedResult);
InspectorTest.log(resultValue === expectedResult ? "SUCCESS" : "FAIL");
InspectorTest.sendCommand("Debugger.resume", { });
next();
}
function handleDebuggerPausedUnexpected(messageObject)
{
InspectorTest.log("Unexpected debugger pause");
InspectorTest.completeTest();
}
}
Check that stepInto at then end of the script go to next user script instead InjectedScriptSource.js.
Stack trace:
boo:0:38
:0:50
Perform stepInto
Stack trace:
boo:0:48
:0:50
Perform stepInto
Stack trace:
:0:51
Perform stepInto
Stack trace:
foo:0:12
\ No newline at end of file
// 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.
print("Check that stepInto at then end of the script go to next user script instead InjectedScriptSource.js.");
InspectorTest.evaluateInPage(
`function foo()
{
return 239;
}`);
InspectorTest.sendCommandOrDie("Debugger.enable", {});
InspectorTest.eventHandler["Debugger.paused"] = debuggerPaused;
InspectorTest.sendCommandOrDie("Runtime.evaluate", { "expression": "(function boo() { setTimeout(foo, 0); debugger; })()" });
var actions = [ "stepInto", "stepInto", "stepInto" ];
function debuggerPaused(result)
{
InspectorTest.log("Stack trace:");
for (var callFrame of result.params.callFrames)
InspectorTest.log(callFrame.functionName + ":" + callFrame.location.lineNumber + ":" + callFrame.location.columnNumber);
InspectorTest.log("");
var action = actions.shift();
if (!action) {
InspectorTest.sendCommandOrDie("Debugger.resume", {}, () => InspectorTest.completeTest());
return;
}
InspectorTest.log("Perform " + action);
InspectorTest.sendCommandOrDie("Debugger." + action, {});
}
{
result : [
[0] : {
configurable : true
enumerable : true
isOwn : true
name : a
value : {
description : 2
type : number
value : 2
}
writable : true
}
]
}
// 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.
InspectorTest.evaluateInPage(
`function testFunction()
{
for (var a of [1]) {
++a;
debugger;
}
}`);
InspectorTest.sendCommandOrDie("Debugger.enable", {});
InspectorTest.eventHandler["Debugger.paused"] = dumpScopeOnPause;
InspectorTest.sendCommandOrDie("Runtime.evaluate", { "expression": "testFunction()" });
var waitScopeObjects = 0;
function dumpScopeOnPause(message)
{
var scopeChain = message.params.callFrames[0].scopeChain;
var localScopeObjectIds = [];
for (var scope of scopeChain) {
if (scope.type === "local")
localScopeObjectIds.push(scope.object.objectId);
}
waitScopeObjects = localScopeObjectIds.length;
if (!waitScopeObjects) {
InspectorTest.completeTest();
} else {
for (var objectId of localScopeObjectIds)
InspectorTest.sendCommandOrDie("Runtime.getProperties", { "objectId" : objectId }, dumpProperties);
}
}
function dumpProperties(message)
{
InspectorTest.logObject(message);
--waitScopeObjects;
if (!waitScopeObjects)
InspectorTest.sendCommandOrDie("Debugger.resume", {}, () => InspectorTest.completeTest());
}
Hash received: 1C6D2E82E4E4F1BA4CB5762843D429DC872EBA18
Hash received: EBF1ECD351E7A3294CB5762843D429DC872EBA18
Hash received: 86A31E7131896CF01BA837945C2894385F369F24
\ No newline at end of file
// 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.
var hashes = new Set(["1C6D2E82E4E4F1BA4CB5762843D429DC872EBA18",
"EBF1ECD351E7A3294CB5762843D429DC872EBA18",
"86A31E7131896CF01BA837945C2894385F369F24"]);
InspectorTest.sendCommandOrDie("Debugger.enable", {}, function() {
InspectorTest.eventHandler["Debugger.scriptParsed"] = function(messageObject)
{
if (hashes.has(messageObject.params.hash))
InspectorTest.log(`Hash received: ${messageObject.params.hash}`);
else
InspectorTest.log(`[FAIL]: unknown hash ${messageObject.params.hash}`);
}
});
function longScript() {
var longScript = "var b = 1;";
for (var i = 0; i < 2024; ++i)
longScript += "++b;";
}
InspectorTest.sendCommandOrDie("Runtime.enable");
InspectorTest.sendCommandOrDie("Runtime.compileScript", { expression: "1", sourceURL: "foo1.js", persistScript: true });
InspectorTest.sendCommandOrDie("Runtime.compileScript", { expression: "239", sourceURL: "foo2.js", persistScript: true });
InspectorTest.sendCommandOrDie("Runtime.compileScript", { expression: "(" + longScript + ")()", sourceURL: "foo3.js", persistScript: true }, step2);
function step2()
{
InspectorTest.completeTest();
}
Pattern parser error: Uncaught SyntaxError: Invalid regular expression: /(foo([)/: Unterminated character class
Paused in
(...):1
Paused in
(...):1
Paused in
qwe:3
baz:3
(...):1
Paused in
bar:3
foo:3
qwe:3
baz:3
(...):1
Paused in
qwe:4
baz:3
(...):1
Paused in
qwe:5
baz:3
(...):1
Paused in
(...):1
// 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.
InspectorTest.evaluateInPage(
`function bar()
{
return 42;
}`);
InspectorTest.evaluateInPage(
`function foo()
{
var a = bar();
return a + 1;
}
//# sourceURL=foo.js`);
InspectorTest.evaluateInPage(
`function qwe()
{
var a = foo();
return a + 1;
}
//# sourceURL=qwe.js`);
InspectorTest.evaluateInPage(
`function baz()
{
var a = qwe();
return a + 1;
}
//# sourceURL=baz.js`);
InspectorTest.sendCommand("Debugger.enable", {});
InspectorTest.sendCommand("Debugger.setBlackboxPatterns", { patterns: [ "foo([" ] }, dumpError);
function dumpError(message)
{
InspectorTest.log(message.error.message);
InspectorTest.eventHandler["Debugger.paused"] = dumpStackAndRunNextCommand;
InspectorTest.sendCommandOrDie("Debugger.setBlackboxPatterns", { patterns: [ "baz\.js", "foo\.js" ] });
InspectorTest.sendCommandOrDie("Runtime.evaluate", { "expression": "debugger;baz()" });
}
var commands = [ "stepInto", "stepInto", "stepInto", "stepOut", "stepInto", "stepInto" ];
function dumpStackAndRunNextCommand(message)
{
InspectorTest.log("Paused in");
var callFrames = message.params.callFrames;
for (var callFrame of callFrames)
InspectorTest.log((callFrame.functionName || "(...)") + ":" + (callFrame.location.lineNumber + 1));
var command = commands.shift();
if (!command) {
InspectorTest.completeTest();
return;
}
InspectorTest.sendCommandOrDie("Debugger." + command, {});
}
setBreakpointByUrl error: undefined
setBreakpoint error: {
"code": -32602,
"message": "Invalid request",
"data": "location: object expected"
}
// 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.
InspectorTest.sendCommand("Debugger.setBreakpointByUrl", { url: "http://example.com", lineNumber: 10 }, didSetBreakpointByUrlBeforeEnable);
function didSetBreakpointByUrlBeforeEnable(message)
{
InspectorTest.log("setBreakpointByUrl error: " + JSON.stringify(message.error, null, 2));
InspectorTest.sendCommand("Debugger.setBreakpoint", {}, didSetBreakpointBeforeEnable);
}
function didSetBreakpointBeforeEnable(message)
{
InspectorTest.log("setBreakpoint error: " + JSON.stringify(message.error, null, 2));
InspectorTest.completeTest();
}
Function evaluate: {"type":"number","value":6,"description":"6"}
PASS, result value: 6
Function evaluate: {"type":"number","value":8,"description":"8"}
PASS, result value: 8
Has error reported: PASS
Reported error is a compile error: PASS
PASS, result value: 1
// 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.
InspectorTest.evaluateInPage(
`function TestExpression(a, b) {
return a + b;
}`);
// A general-purpose engine for sending a sequence of protocol commands.
// The clients provide requests and response handlers, while the engine catches
// errors and makes sure that once there's nothing to do completeTest() is called.
// @param step is an object with command, params and callback fields
function runRequestSeries(step) {
processStep(step);
function processStep(currentStep) {
try {
processStepOrFail(currentStep);
} catch (e) {
InspectorTest.log(e.stack);
InspectorTest.completeTest();
}
}
function processStepOrFail(currentStep) {
if (!currentStep) {
InspectorTest.completeTest();
return;
}
if (!currentStep.command) {
// A simple loopback step.
var next = currentStep.callback();
processStep(next);
return;
}
var innerCallback = function(response) {
var next;
if ("error" in response) {
if (!("errorHandler" in currentStep)) {
// Error message is not logged intentionally, it may be platform-specific.
InspectorTest.log("Protocol command '" + currentStep.command + "' failed");
InspectorTest.completeTest();
return;
}
try {
next = currentStep.errorHandler(response.error);
} catch (e) {
InspectorTest.log(e.stack);
InspectorTest.completeTest();
return;
}
} else {
try {
next = currentStep.callback(response.result);
} catch (e) {
InspectorTest.log(e.stack);
InspectorTest.completeTest();
return;
}
}
processStep(next);
}
InspectorTest.sendCommand(currentStep.command, currentStep.params, innerCallback);
}
}
function logEqualsCheck(actual, expected)
{
if (actual === expected) {
InspectorTest.log("PASS, result value: " + actual);
} else {
InspectorTest.log("FAIL, actual value: " + actual + ", expected: " + expected);
}
}
function logCheck(description, success)
{
InspectorTest.log(description + ": " + (success ? "PASS" : "FAIL"));
}
var firstStep = { callback: enableDebugger };
runRequestSeries(firstStep);
function enableDebugger() {
return { command: "Debugger.enable", params: {}, callback: evalFunction };
}
function evalFunction(response) {
var expression = "TestExpression(2, 4)";
return { command: "Runtime.evaluate", params: { expression: expression }, callback: callbackEvalFunction };
}
function callbackEvalFunction(result) {
InspectorTest.log("Function evaluate: " + JSON.stringify(result.result));
logEqualsCheck(result.result.value, 6);
return { command: "Runtime.evaluate", params: { expression: "TestExpression" }, callback: callbackEvalFunctionObject };
}
function callbackEvalFunctionObject(result) {
return { command: "Runtime.getProperties", params: { objectId: result.result.objectId }, callback: callbackFunctionDetails };
}
function callbackFunctionDetails(result)
{
var scriptId;
for (var prop of result.internalProperties) {
if (prop.name === "[[FunctionLocation]]")
scriptId = prop.value.value.scriptId;
}
return createScriptManipulationArc(scriptId, null);
}
// Several steps with scriptId in context.
function createScriptManipulationArc(scriptId, next) {
return { command: "Debugger.getScriptSource", params: { scriptId: scriptId }, callback: callbackGetScriptSource };
var originalText;
function callbackGetScriptSource(result) {
originalText = result.scriptSource;
var patched = originalText.replace("a + b", "a * b");
return { command: "Debugger.setScriptSource", params: { scriptId: scriptId, scriptSource: patched }, callback: callbackSetScriptSource };
}
function callbackSetScriptSource(result) {
var expression = "TestExpression(2, 4)";
return { command: "Runtime.evaluate", params: { expression: expression }, callback: callbackEvalFunction2 };
}
function callbackEvalFunction2(result) {
InspectorTest.log("Function evaluate: " + JSON.stringify(result.result));
logEqualsCheck(result.result.value, 8);
var patched = originalText.replace("a + b", "a # b");
return { command: "Debugger.setScriptSource", params: { scriptId: scriptId, scriptSource: patched }, callback: errorCallbackSetScriptSource2 };
}
function errorCallbackSetScriptSource2(result) {
var exceptionDetails = result.exceptionDetails;
logCheck("Has error reported", !!exceptionDetails);
logCheck("Reported error is a compile error", !!exceptionDetails);
if (exceptionDetails)
logEqualsCheck(exceptionDetails.lineNumber, 1);
return next;
}
}
testFunction:9
testFunction:11
testFunction:9
testFunction:11
\ No newline at end of file
// 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.
InspectorTest.evaluateInPage(
`function testFunction()
{
function foo()
{
try {
throw new Error();
} catch (e) {
}
}
debugger;
foo();
console.log("completed");
}`);
InspectorTest.sendCommandOrDie("Debugger.enable", {});
InspectorTest.sendCommandOrDie("Runtime.enable", {});
step1();
function step1()
{
InspectorTest.sendCommandOrDie("Runtime.evaluate", { "expression": "setTimeout(testFunction, 0);"});
var commands = [ "Print", "stepOver", "stepOver", "Print", "resume" ];
InspectorTest.eventHandler["Debugger.paused"] = function(messageObject)
{
var command = commands.shift();
if (command === "Print") {
var callFrames = messageObject.params.callFrames;
for (var callFrame of callFrames)
InspectorTest.log(callFrame.functionName + ":" + callFrame.location.lineNumber);
command = commands.shift();
}
if (command)
InspectorTest.sendCommandOrDie("Debugger." + command, {});
}
InspectorTest.eventHandler["Runtime.consoleAPICalled"] = function(messageObject)
{
if (messageObject.params.args[0].value === "completed") {
if (commands.length)
InspectorTest.log("[FAIL]: execution was resumed too earlier.")
step2();
}
}
}
function step2()
{
InspectorTest.sendCommandOrDie("Runtime.evaluate", { "expression": "setTimeout(testFunction, 0);"});
var commands = [ "Print", "stepOver", "stepInto", "stepOver", "stepOver", "Print", "resume" ];
InspectorTest.eventHandler["Debugger.paused"] = function(messageObject)
{
var command = commands.shift();
if (command === "Print") {
var callFrames = messageObject.params.callFrames;
for (var callFrame of callFrames)
InspectorTest.log(callFrame.functionName + ":" + callFrame.location.lineNumber);
command = commands.shift();
}
if (command)
InspectorTest.sendCommandOrDie("Debugger." + command, {});
}
InspectorTest.eventHandler["Runtime.consoleAPICalled"] = function(messageObject)
{
if (messageObject.params.args[0].value === "completed") {
if (commands.length)
InspectorTest.log("[FAIL]: execution was resumed too earlier.")
InspectorTest.completeTest();
}
}
}
foo: 8:4
blackboxedBoo: 3:12
notBlackboxedFoo: 3:12
blackboxedFoo: 10:12
notBlackboxedBoo: 17:12
testFunction: 2:4
Try to set positions: [{"lineNumber":0,"columnNumber":0},{"lineNumber":0,"columnNumber":0}]
Input positions array is not sorted or contains duplicate values.
Try to set positions: [{"lineNumber":0,"columnNumber":1},{"lineNumber":0,"columnNumber":0}]
Input positions array is not sorted or contains duplicate values.
Try to set positions: [{"lineNumber":0,"columnNumber":-1}]
Position missing 'column' or 'column' < 0.
action: stepOut
notBlackboxedFoo: 4:4
blackboxedFoo: 10:12
notBlackboxedBoo: 17:12
testFunction: 2:4
action: stepOut
notBlackboxedBoo: 18:4
testFunction: 2:4
action: stepOut
testFunction: 3:4
action: stepInto
notBlackboxedBoo: 16:12
testFunction: 3:4
action: stepOver
action: stepInto
notBlackboxedFoo: 2:12
blackboxedFoo: 10:12
notBlackboxedBoo: 17:12
testFunction: 3:4
action: stepOver
action: stepInto
foo: 8:4
blackboxedBoo: 3:12
notBlackboxedFoo: 3:12
blackboxedFoo: 10:12
notBlackboxedBoo: 17:12
testFunction: 3:4
action: stepOver
action: stepInto
foo: 10:0
blackboxedBoo: 3:12
notBlackboxedFoo: 3:12
blackboxedFoo: 10:12
notBlackboxedBoo: 17:12
testFunction: 3:4
// 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.
InspectorTest.evaluateInPage(
`function blackboxedBoo()
{
var a = 42;
var b = foo();
return a + b;
}
//# sourceURL=blackboxed-script.js`);
InspectorTest.evaluateInPage(
`function notBlackboxedFoo()
{
var a = 42;
var b = blackboxedBoo();
return a + b;
}
function blackboxedFoo()
{
var a = 42;
var b = notBlackboxedFoo();
return a + b;
}
function notBlackboxedBoo()
{
var a = 42;
var b = blackboxedFoo();
return a + b;
}
//# sourceURL=mixed-source.js`);
InspectorTest.evaluateInPage(
`function testFunction()
{
notBlackboxedBoo(); // for setup ranges and stepOut
notBlackboxedBoo(); // for stepIn
}
function foo()
{
debugger;
return 239;
}`);
InspectorTest.eventHandler["Debugger.paused"] = setBlackboxedScriptRanges;
InspectorTest.sendCommandOrDie("Debugger.enable", {}, callTestFunction);
function callTestFunction(response)
{
InspectorTest.sendCommand("Runtime.evaluate", { expression: "setTimeout(testFunction, 0);"});
}
function setBlackboxedScriptRanges(response)
{
var callFrames = response.params.callFrames;
printCallFrames(callFrames);
InspectorTest.sendCommand("Debugger.setBlackboxedRanges", {
scriptId: callFrames[1].location.scriptId,
positions: [ { lineNumber: 0, columnNumber: 0 } ] // blackbox ranges for blackboxed.js
}, setIncorrectRanges.bind(null, callFrames[2].location.scriptId));
}
var incorrectPositions = [
[ { lineNumber: 0, columnNumber: 0 }, { lineNumber: 0, columnNumber: 0 } ],
[ { lineNumber: 0, columnNumber: 1 }, { lineNumber: 0, columnNumber: 0 } ],
[ { lineNumber: 0, columnNumber: -1 } ],
];
function setIncorrectRanges(scriptId, response)
{
if (response.error)
InspectorTest.log(response.error.message);
var positions = incorrectPositions.shift();
if (!positions) {
setMixedSourceRanges(scriptId);
return;
}
InspectorTest.log("Try to set positions: " + JSON.stringify(positions));
InspectorTest.sendCommand("Debugger.setBlackboxedRanges", {
scriptId: scriptId,
positions: positions
}, setIncorrectRanges.bind(null, scriptId));
}
function setMixedSourceRanges(scriptId)
{
InspectorTest.eventHandler["Debugger.paused"] = runAction;
InspectorTest.sendCommandOrDie("Debugger.setBlackboxedRanges", {
scriptId: scriptId,
positions: [ { lineNumber: 8, columnNumber: 0 }, { lineNumber: 15, columnNumber: 0 } ] // blackbox ranges for mixed.js
}, runAction);
}
var actions = [ "stepOut", "print", "stepOut", "print", "stepOut", "print",
"stepInto", "print", "stepOver", "stepInto", "print", "stepOver", "stepInto", "print",
"stepOver", "stepInto", "print" ];
function runAction(response)
{
var action = actions.shift();
if (!action)
InspectorTest.completeTest();
if (action === "print") {
printCallFrames(response.params.callFrames);
runAction({});
} else {
InspectorTest.log("action: " + action);
InspectorTest.sendCommandOrDie("Debugger." + action, {});
}
}
function printCallFrames(callFrames)
{
var topCallFrame = callFrames[0];
if (topCallFrame.functionName.startsWith("blackboxed"))
InspectorTest.log("FAIL: blackboxed function in top call frame");
for (var callFrame of callFrames)
InspectorTest.log(callFrame.functionName + ": " + callFrame.location.lineNumber + ":" + callFrame.location.columnNumber);
InspectorTest.log("");
}
Paused on 'debugger;'
Variable value changed
Stacktrace re-read again
Scope variables downloaded anew
New variable is 55, expected is 55, old was: 2
SUCCESS
// 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.
InspectorTest.evaluateInPage(
`function TestFunction()
{
var a = 2;
debugger;
debugger;
}`);
var newVariableValue = 55;
InspectorTest.sendCommand("Debugger.enable", {});
InspectorTest.eventHandler["Debugger.paused"] = handleDebuggerPaused;
InspectorTest.sendCommand("Runtime.evaluate", { "expression": "setTimeout(TestFunction, 0)" });
function handleDebuggerPaused(messageObject)
{
InspectorTest.log("Paused on 'debugger;'");
InspectorTest.eventHandler["Debugger.paused"] = undefined;
var topFrame = messageObject.params.callFrames[0];
var topFrameId = topFrame.callFrameId;
InspectorTest.sendCommand("Debugger.evaluateOnCallFrame", { "callFrameId": topFrameId, "expression": "a = " + newVariableValue }, callbackChangeValue);
}
function callbackChangeValue(response)
{
InspectorTest.log("Variable value changed");
InspectorTest.eventHandler["Debugger.paused"] = callbackGetBacktrace;
InspectorTest.sendCommand("Debugger.resume", { });
}
function callbackGetBacktrace(response)
{
InspectorTest.log("Stacktrace re-read again");
var localScope = response.params.callFrames[0].scopeChain[0];
InspectorTest.sendCommand("Runtime.getProperties", { "objectId": localScope.object.objectId }, callbackGetProperties);
}
function callbackGetProperties(response)
{
InspectorTest.log("Scope variables downloaded anew");
var varNamedA;
var propertyList = response.result.result;
for (var i = 0; i < propertyList.length; i++) {
if (propertyList[i].name === "a") {
varNamedA = propertyList[i];
break;
}
}
if (varNamedA) {
var actualValue = varNamedA.value.value;
InspectorTest.log("New variable is " + actualValue + ", expected is " + newVariableValue + ", old was: 2");
InspectorTest.log(actualValue === newVariableValue ? "SUCCESS" : "FAIL");
} else {
InspectorTest.log("Failed to find variable in scope");
}
InspectorTest.completeTest();
}
......@@ -32,14 +32,6 @@ class ChannelImpl final : public v8_inspector::V8Inspector::Channel {
DISALLOW_COPY_AND_ASSIGN(ChannelImpl);
};
InspectorClientImpl* InspectorClientFromContext(
v8::Local<v8::Context> context) {
InspectorClientImpl* inspector_client = static_cast<InspectorClientImpl*>(
context->GetAlignedPointerFromEmbedderData(kInspectorClientIndex));
CHECK(inspector_client);
return inspector_client;
}
} // namespace
class ConnectTask : public TaskRunner::Task {
......@@ -104,14 +96,12 @@ void InspectorClientImpl::quitMessageLoopOnPause() {
task_runner_->QuitMessageLoop();
}
v8_inspector::V8Inspector* InspectorClientImpl::InspectorFromContext(
v8::Local<v8::Context> context) {
return InspectorClientFromContext(context)->inspector_.get();
}
v8_inspector::V8InspectorSession* InspectorClientImpl::SessionFromContext(
v8::Local<v8::Context> context) {
return InspectorClientFromContext(context)->session_.get();
InspectorClientImpl* inspector_client = static_cast<InspectorClientImpl*>(
context->GetAlignedPointerFromEmbedderData(kInspectorClientIndex));
CHECK(inspector_client);
return inspector_client->session_.get();
}
class SendMessageToBackendTask : public TaskRunner::Task {
......
......@@ -25,9 +25,6 @@ class InspectorClientImpl : public v8_inspector::V8InspectorClient {
v8::base::Semaphore* ready_semaphore);
virtual ~InspectorClientImpl();
static v8_inspector::V8Inspector* InspectorFromContext(
v8::Local<v8::Context> context);
private:
// V8InspectorClient implementation.
v8::Local<v8::Context> ensureDefaultContextInGroup(
......
// 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.
#include "include/libplatform/libplatform.h"
#include "include/v8.h"
#include "src/base/platform/platform.h"
#include "src/flags.h"
#include "src/utils.h"
#include "src/vector.h"
#include "test/inspector/inspector-impl.h"
#include "test/inspector/task-runner.h"
namespace {
void Exit() {
fflush(stdout);
fflush(stderr);
_exit(0);
}
class UtilsExtension : public v8::Extension {
public:
UtilsExtension()
: v8::Extension("v8_inspector/utils",
"native function print(); native function quit();") {}
virtual v8::Local<v8::FunctionTemplate> GetNativeFunctionTemplate(
v8::Isolate* isolate, v8::Local<v8::String> name) {
v8::Local<v8::Context> context = isolate->GetCurrentContext();
if (name->Equals(context, v8::String::NewFromUtf8(
isolate, "print", v8::NewStringType::kNormal)
.ToLocalChecked())
.FromJust()) {
return v8::FunctionTemplate::New(isolate, UtilsExtension::Print);
} else if (name->Equals(context,
v8::String::NewFromUtf8(isolate, "quit",
v8::NewStringType::kNormal)
.ToLocalChecked())
.FromJust()) {
return v8::FunctionTemplate::New(isolate, UtilsExtension::Quit);
}
return v8::Local<v8::FunctionTemplate>();
}
private:
static void Print(const v8::FunctionCallbackInfo<v8::Value>& args) {
for (int i = 0; i < args.Length(); i++) {
v8::HandleScope handle_scope(args.GetIsolate());
if (i != 0) {
printf(" ");
}
// Explicitly catch potential exceptions in toString().
v8::TryCatch try_catch(args.GetIsolate());
v8::Local<v8::Value> arg = args[i];
v8::Local<v8::String> str_obj;
if (arg->IsSymbol()) {
arg = v8::Local<v8::Symbol>::Cast(arg)->Name();
}
if (!arg->ToString(args.GetIsolate()->GetCurrentContext())
.ToLocal(&str_obj)) {
try_catch.ReThrow();
return;
}
v8::String::Utf8Value str(str_obj);
int n =
static_cast<int>(fwrite(*str, sizeof(**str), str.length(), stdout));
if (n != str.length()) {
printf("Error in fwrite\n");
Quit(args);
}
}
printf("\n");
fflush(stdout);
}
static void Quit(const v8::FunctionCallbackInfo<v8::Value>& args) { Exit(); }
};
class SetTimeoutTask : public TaskRunner::Task {
public:
SetTimeoutTask(v8::Isolate* isolate, v8::Local<v8::Function> function)
: function_(isolate, function) {}
virtual ~SetTimeoutTask() {}
bool is_inspector_task() final { return false; }
void Run(v8::Isolate* isolate,
const v8::Global<v8::Context>& global_context) override {
v8::MicrotasksScope microtasks_scope(isolate,
v8::MicrotasksScope::kRunMicrotasks);
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = global_context.Get(isolate);
v8::Context::Scope context_scope(context);
v8::Local<v8::Function> function = function_.Get(isolate);
v8::MaybeLocal<v8::Value> result;
v8_inspector::V8Inspector* inspector =
InspectorClientImpl::InspectorFromContext(context);
if (inspector) inspector->willExecuteScript(context, function->ScriptId());
result = function->Call(context, context->Global(), 0, nullptr);
if (inspector) inspector->didExecuteScript(context);
}
private:
v8::Global<v8::Function> function_;
};
class SetTimeoutExtension : public v8::Extension {
public:
SetTimeoutExtension()
: v8::Extension("v8_inspector/setTimeout",
"native function setTimeout();") {}
virtual v8::Local<v8::FunctionTemplate> GetNativeFunctionTemplate(
v8::Isolate* isolate, v8::Local<v8::String> name) {
return v8::FunctionTemplate::New(isolate, SetTimeoutExtension::SetTimeout);
}
private:
static void SetTimeout(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::Isolate* isolate = args.GetIsolate();
if (args.Length() != 2 || !args[1]->IsNumber() || !args[0]->IsFunction() ||
args[1].As<v8::Number>()->Value() != 0.0) {
fprintf(stderr,
"Internal error: only setTimeout(function, 0) is supported.");
Exit();
}
v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext();
TaskRunner::FromContext(context)->Append(new SetTimeoutTask(
args.GetIsolate(), v8::Local<v8::Function>::Cast(args[0])));
}
};
v8_inspector::String16 ToString16(const v8_inspector::StringView& string) {
if (string.is8Bit())
return v8_inspector::String16(
reinterpret_cast<const char*>(string.characters8()), string.length());
return v8_inspector::String16(
reinterpret_cast<const uint16_t*>(string.characters16()),
string.length());
}
class FrontendChannelImpl : public InspectorClientImpl::FrontendChannel {
public:
explicit FrontendChannelImpl(TaskRunner* frontend_task_runner)
: frontend_task_runner_(frontend_task_runner) {}
virtual ~FrontendChannelImpl() {}
void SendMessageToFrontend(const v8_inspector::StringView& message) final {
v8_inspector::String16Builder script;
script.append("InspectorTest.dispatchMessage(");
script.append(ToString16(message));
script.append(")");
frontend_task_runner_->Append(new ExecuteStringTask(script.toString()));
}
private:
TaskRunner* frontend_task_runner_;
};
} // namespace
int main(int argc, char* argv[]) {
v8::V8::InitializeICUDefaultLocation(argv[0]);
v8::Platform* platform = v8::platform::CreateDefaultPlatform();
v8::V8::InitializePlatform(platform);
v8::internal::FlagList::SetFlagsFromCommandLine(&argc, argv, true);
v8::V8::InitializeExternalStartupData(argv[0]);
v8::V8::Initialize();
SetTimeoutExtension set_timeout_extension;
v8::RegisterExtension(&set_timeout_extension);
UtilsExtension utils_extension;
v8::RegisterExtension(&utils_extension);
SendMessageToBackendExtension send_message_to_backend_extension;
v8::RegisterExtension(&send_message_to_backend_extension);
v8::base::Semaphore ready_semaphore(0);
const char* backend_extensions[] = {"v8_inspector/setTimeout"};
v8::ExtensionConfiguration backend_configuration(
arraysize(backend_extensions), backend_extensions);
TaskRunner backend_runner(&backend_configuration, &ready_semaphore);
ready_semaphore.Wait();
SendMessageToBackendExtension::set_backend_task_runner(&backend_runner);
const char* frontend_extensions[] = {"v8_inspector/utils",
"v8_inspector/frontend"};
v8::ExtensionConfiguration frontend_configuration(
arraysize(frontend_extensions), frontend_extensions);
TaskRunner frontend_runner(&frontend_configuration, &ready_semaphore);
ready_semaphore.Wait();
FrontendChannelImpl frontend_channel(&frontend_runner);
InspectorClientImpl inspector_client(&backend_runner, &frontend_channel,
&ready_semaphore);
ready_semaphore.Wait();
for (int i = 1; i < argc; ++i) {
if (argv[i][0] == '-') break;
bool exists = false;
v8::internal::Vector<const char> chars =
v8::internal::ReadFile(argv[i], &exists, true);
if (!exists) {
fprintf(stderr, "Internal error: script file doesn't exists: %s\n",
argv[i]);
Exit();
}
v8_inspector::String16 source =
v8_inspector::String16::fromUTF8(chars.start(), chars.length());
frontend_runner.Append(new ExecuteStringTask(source));
}
frontend_runner.Join();
return 0;
}
......@@ -8,7 +8,6 @@
'inspector_protocol_sources': [
'inspector-impl.cc',
'inspector-impl.h',
'inspector-test.cc',
'task-runner.cc',
'task-runner.h',
],
......
# 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.
[
]
{
id : 1
result : {
result : {
type : string
value : Привет мир
}
}
}
// 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.
const id = ++InspectorTest._requestId;
var command = { "method": "Runtime.evaluate", "params": { expression: "\"!!!\"" }, "id": id };
InspectorTest.sendRawCommand(id, JSON.stringify(command).replace("!!!", "\\u041F\\u0440\\u0438\\u0432\\u0435\\u0442 \\u043C\\u0438\\u0440"), step2);
function step2(msg)
{
msg.id = 1;
InspectorTest.logObject(msg);
InspectorTest.completeTest();
}
// 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.
InspectorTest = {};
InspectorTest._dispatchTable = new Map();
InspectorTest._requestId = 0;
InspectorTest._dumpInspectorProtocolMessages = false;
InspectorTest.eventHandler = {};
InspectorTest.startDumpingProtocolMessages = function()
{
InspectorTest._dumpInspectorProtocolMessages = true;
}
InspectorTest.sendCommand = function(method, params, handler)
{
var requestId = ++InspectorTest._requestId;
var messageObject = { "id": requestId, "method": method, "params": params };
InspectorTest.sendRawCommand(requestId, JSON.stringify(messageObject), handler);
}
InspectorTest.sendRawCommand = function(requestId, command, handler)
{
if (InspectorTest._dumpInspectorProtocolMessages)
print("frontend: " + command);
InspectorTest._dispatchTable.set(requestId, handler);
sendMessageToBackend(command);
}
InspectorTest.sendCommandOrDie = function(command, properties, callback)
{
InspectorTest.sendCommand(command, properties, commandCallback);
function commandCallback(msg)
{
if (msg.error) {
InspectorTest.log("ERROR: " + msg.error.message);
InspectorTest.completeTest();
return;
}
if (callback)
callback(msg.result);
}
}
InspectorTest.sendCommandPromise = function(method, params)
{
return new Promise(fulfill => InspectorTest.sendCommand(method, params, fulfill));
}
InspectorTest.waitForEventPromise = function(eventName)
{
return new Promise(fulfill => InspectorTest.eventHandler[eventName] = fullfillAndClearListener.bind(null, fulfill));
function fullfillAndClearListener(fulfill, result)
{
delete InspectorTest.eventHandler[eventName];
fulfill(result);
}
}
InspectorTest.dispatchMessage = function(messageObject)
{
if (InspectorTest._dumpInspectorProtocolMessages)
print("backend: " + JSON.stringify(messageObject));
try {
var messageId = messageObject["id"];
if (typeof messageId === "number") {
var handler = InspectorTest._dispatchTable.get(messageId);
if (handler) {
handler(messageObject);
InspectorTest._dispatchTable.delete(messageId);
}
} else {
var eventName = messageObject["method"];
var eventHandler = InspectorTest.eventHandler[eventName];
if (eventHandler)
eventHandler(messageObject);
}
} catch (e) {
InspectorTest.log("Exception when dispatching message: " + e + "\n" + e.stack + "\n message = " + JSON.stringify(messageObject, null, 2));
InspectorTest.completeTest();
}
}
InspectorTest.log = print.bind(null);
InspectorTest.logObject = function(object, title)
{
var lines = [];
function dumpValue(value, prefix, prefixWithName)
{
if (typeof value === "object" && value !== null) {
if (value instanceof Array)
dumpItems(value, prefix, prefixWithName);
else
dumpProperties(value, prefix, prefixWithName);
} else {
lines.push(prefixWithName + String(value).replace(/\n/g, " "));
}
}
function dumpProperties(object, prefix, firstLinePrefix)
{
prefix = prefix || "";
firstLinePrefix = firstLinePrefix || prefix;
lines.push(firstLinePrefix + "{");
var propertyNames = Object.keys(object);
propertyNames.sort();
for (var i = 0; i < propertyNames.length; ++i) {
var name = propertyNames[i];
if (!object.hasOwnProperty(name))
continue;
var prefixWithName = " " + prefix + name + " : ";
dumpValue(object[name], " " + prefix, prefixWithName);
}
lines.push(prefix + "}");
}
function dumpItems(object, prefix, firstLinePrefix)
{
prefix = prefix || "";
firstLinePrefix = firstLinePrefix || prefix;
lines.push(firstLinePrefix + "[");
for (var i = 0; i < object.length; ++i)
dumpValue(object[i], " " + prefix, " " + prefix + "[" + i + "] : ");
lines.push(prefix + "]");
}
dumpValue(object, "", title);
InspectorTest.log(lines.join("\n"));
}
InspectorTest.completeTest = quit.bind(null);
InspectorTest.evaluateInPage = function(string, callback)
{
InspectorTest.sendCommand("Runtime.evaluate", { "expression": string }, function(message) {
if (message.error) {
InspectorTest.log("Error while executing '" + string + "': " + message.error.message);
InspectorTest.completeTest();
}
else if (callback)
callback(message.result.result.value);
});
};
InspectorTest.checkExpectation = function(fail, name, messageObject)
{
if (fail === !!messageObject.error) {
InspectorTest.log("PASS: " + name);
return true;
}
InspectorTest.log("FAIL: " + name + ": " + JSON.stringify(messageObject));
InspectorTest.completeTest();
return false;
}
InspectorTest.expectedSuccess = InspectorTest.checkExpectation.bind(null, false);
InspectorTest.expectedError = InspectorTest.checkExpectation.bind(null, true);
InspectorTest.runTestSuite = function(testSuite)
{
function nextTest()
{
if (!testSuite.length) {
InspectorTest.completeTest();
return;
}
var fun = testSuite.shift();
InspectorTest.log("\nRunning test: " + fun.name);
fun(nextTest);
}
nextTest();
}
Tests that Runtime.awaitPromise works.
Running test: testResolvedPromise
{
result : {
description : 239
type : number
value : 239
}
}
Running test: testRejectedPromise
{
exceptionDetails : {
columnNumber : 0
exception : {
objectId : 0
type : object
value : {
a : 1
}
}
exceptionId : 0
lineNumber : 0
stackTrace : {
callFrames : [
]
}
text : Uncaught (in promise)
}
result : {
type : object
value : {
a : 1
}
}
}
Running test: testRejectedPromiseWithStack
{
exceptionDetails : {
columnNumber : 0
exception : {
description : 239
objectId : 0
type : number
value : 239
}
exceptionId : 0
lineNumber : 0
stackTrace : {
callFrames : [
]
parent : {
callFrames : [
[0] : {
columnNumber : 4
functionName : rejectPromise
lineNumber : 17
scriptId : 0
url : test.js
}
[1] : {
columnNumber : 0
functionName : (anonymous)
lineNumber : 0
scriptId : 0
url : (empty)
}
]
description : Promise.reject
}
}
text : Uncaught (in promise)
}
result : {
description : 239
type : number
value : 239
}
}
Running test: testPendingPromise
{
result : {
description : 239
type : number
value : 239
}
}
Running test: testResolvedWithoutArgsPromise
{
result : {
type : undefined
}
}
Running test: testGarbageCollectedPromise
{
code : -32000
message : Promise was collected
}
// 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
print("Tests that Runtime.awaitPromise works.");
InspectorTest.evaluateInPage(
`
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;
}
//# sourceURL=test.js`);
InspectorTest.sendCommandPromise("Debugger.enable", {})
.then(() => InspectorTest.sendCommandPromise("Debugger.setAsyncCallStackDepth", { maxDepth: 128 }))
.then(() => testSuite());
function dumpResult(result)
{
if (result.exceptionDetails) {
if (result.exceptionDetails.stackTrace && result.exceptionDetails.stackTrace.parent) {
for (var frame of result.exceptionDetails.stackTrace.parent.callFrames) {
frame.scriptId = 0;
if (!frame.url)
frame.url = "(empty)";
if (!frame.functionName)
frame.functionName = "(anonymous)";
}
}
result.exceptionDetails.exceptionId = 0;
if (result.exceptionDetails.exception)
result.exceptionDetails.exception.objectId = 0;
}
InspectorTest.logObject(result);
}
function testSuite()
{
InspectorTest.runTestSuite([
function testResolvedPromise(next)
{
InspectorTest.sendCommandPromise("Runtime.evaluate", { expression: "Promise.resolve(239)"})
.then((result) => InspectorTest.sendCommandPromise("Runtime.awaitPromise", { promiseObjectId: result.result.result.objectId, returnByValue: false, generatePreview: true }))
.then((result) => dumpResult(result.result))
.then(() => next());
},
function testRejectedPromise(next)
{
InspectorTest.sendCommandPromise("Runtime.evaluate", { expression: "Promise.reject({ a : 1 })"})
.then((result) => InspectorTest.sendCommandPromise("Runtime.awaitPromise", { promiseObjectId: result.result.result.objectId, returnByValue: true, generatePreview: false }))
.then((result) => dumpResult(result.result))
.then(() => next());
},
function testRejectedPromiseWithStack(next)
{
InspectorTest.sendCommandPromise("Runtime.evaluate", { expression: "createPromise()"})
.then((result) => scheduleRejectAndAwaitPromise(result))
.then((result) => dumpResult(result.result))
.then(() => next());
function scheduleRejectAndAwaitPromise(result)
{
var promise = InspectorTest.sendCommandPromise("Runtime.awaitPromise", { promiseObjectId: result.result.result.objectId });
InspectorTest.sendCommandPromise("Runtime.evaluate", { expression: "rejectPromise()" });
return promise;
}
},
function testPendingPromise(next)
{
InspectorTest.sendCommandPromise("Runtime.evaluate", { expression: "createPromise()"})
.then((result) => scheduleFulfillAndAwaitPromise(result))
.then((result) => dumpResult(result.result))
.then(() => next());
function scheduleFulfillAndAwaitPromise(result)
{
var promise = InspectorTest.sendCommandPromise("Runtime.awaitPromise", { promiseObjectId: result.result.result.objectId });
InspectorTest.sendCommandPromise("Runtime.evaluate", { expression: "resolvePromise()" });
return promise;
}
},
function testResolvedWithoutArgsPromise(next)
{
InspectorTest.sendCommandPromise("Runtime.evaluate", { expression: "Promise.resolve()"})
.then((result) => InspectorTest.sendCommandPromise("Runtime.awaitPromise", { promiseObjectId: result.result.result.objectId, returnByValue: true, generatePreview: false }))
.then((result) => dumpResult(result.result))
.then(() => next());
},
function testGarbageCollectedPromise(next)
{
InspectorTest.sendCommandPromise("Runtime.evaluate", { expression: "new Promise(() => undefined)" })
.then((result) => scheduleGCAndawaitPromise(result))
.then((result) => InspectorTest.logObject(result.error))
.then(() => next());
function scheduleGCAndawaitPromise(result)
{
var objectId = result.result.result.objectId;
var promise = InspectorTest.sendCommandPromise("Runtime.awaitPromise", { promiseObjectId: objectId });
gcPromise(objectId);
return promise;
}
function gcPromise(objectId)
{
InspectorTest.sendCommandPromise("Runtime.releaseObject", { objectId: objectId})
.then(() => InspectorTest.sendCommandPromise("Runtime.evaluate", { expression: "gc()" }));
}
}
]);
}
Tests that Runtime.callFunctionOn works with awaitPromise flag.
Running test: testArguments
{
result : {
type : string
value : undefined|NaN|[object Object]|[object Object]
}
}
Running test: testSyntaxErrorInFunction
{
exceptionDetails : {
columnNumber : 2
exception : {
className : SyntaxError
description : SyntaxError: Unexpected token }
objectId : 0
subtype : error
type : object
}
exceptionId : 0
lineNumber : 1
scriptId : 0
text : Uncaught
}
result : {
className : SyntaxError
description : SyntaxError: Unexpected token }
objectId : [ObjectId]
subtype : error
type : object
}
}
Running test: testExceptionInFunctionExpression
{
exceptionDetails : {
columnNumber : 15
exception : {
className : Error
description : Error at <anonymous>:1:22 at <anonymous>:1:36
objectId : 0
subtype : error
type : object
}
exceptionId : 0
lineNumber : 0
scriptId : 0
text : Uncaught
}
result : {
className : Error
description : Error at <anonymous>:1:22 at <anonymous>:1:36
objectId : [ObjectId]
subtype : error
type : object
}
}
Running test: testFunctionReturnNotPromise
{
code : -32000
message : Result of the function call is not a promise
}
Running test: testFunctionReturnResolvedPromiseReturnByValue
{
result : {
type : object
value : {
a : 3
}
}
}
Running test: testFunctionReturnResolvedPromiseWithPreview
{
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
{
exceptionDetails : {
columnNumber : 0
exception : {
objectId : 0
type : object
value : {
a : 3
}
}
exceptionId : 0
lineNumber : 0
stackTrace : {
callFrames : [
]
}
text : Uncaught (in promise)
}
result : {
type : object
value : {
a : 3
}
}
}
// 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.
print("Tests that Runtime.callFunctionOn works with awaitPromise flag.");
InspectorTest.runTestSuite([
function testArguments(next)
{
callFunctionOn(
"({a : 1})",
"function(arg1, arg2, arg3, arg4) { return \"\" + arg1 + \"|\" + arg2 + \"|\" + arg3 + \"|\" + arg4; }",
[ "undefined", "NaN", "({a:2})", "this"],
/* returnByValue */ true,
/* generatePreview */ false,
/* awaitPromise */ false)
.then((result) => dumpResult(result.result))
.then(() => next());
},
function testSyntaxErrorInFunction(next)
{
callFunctionOn(
"({a : 1})",
"\n }",
[],
/* returnByValue */ false,
/* generatePreview */ false,
/* awaitPromise */ true)
.then((result) => dumpResult(result.result))
.then(() => next());
},
function testExceptionInFunctionExpression(next)
{
callFunctionOn(
"({a : 1})",
"(function() { throw new Error() })()",
[],
/* returnByValue */ false,
/* generatePreview */ false,
/* awaitPromise */ true)
.then((result) => dumpResult(result.result))
.then(() => next());
},
function testFunctionReturnNotPromise(next)
{
callFunctionOn(
"({a : 1})",
"(function() { return 239; })",
[],
/* returnByValue */ false,
/* generatePreview */ false,
/* awaitPromise */ true)
.then((result) => InspectorTest.logObject(result.error))
.then(() => next());
},
function testFunctionReturnResolvedPromiseReturnByValue(next)
{
callFunctionOn(
"({a : 1})",
"(function(arg) { return Promise.resolve({a : this.a + arg.a}); })",
[ "({a:2})" ],
/* returnByValue */ true,
/* generatePreview */ false,
/* awaitPromise */ true)
.then((result) => dumpResult(result.result))
.then(() => next());
},
function testFunctionReturnResolvedPromiseWithPreview(next)
{
callFunctionOn(
"({a : 1})",
"(function(arg) { return Promise.resolve({a : this.a + arg.a}); })",
[ "({a:2})" ],
/* returnByValue */ false,
/* generatePreview */ true,
/* awaitPromise */ true)
.then((result) => dumpResult(result.result))
.then(() => next());
},
function testFunctionReturnRejectedPromise(next)
{
callFunctionOn(
"({a : 1})",
"(function(arg) { return Promise.reject({a : this.a + arg.a}); })",
[ "({a:2})" ],
/* returnByValue */ true,
/* generatePreview */ false,
/* awaitPromise */ true)
.then((result) => dumpResult(result.result))
.then(() => next());
}
]);
function callFunctionOn(objectExpression, functionDeclaration, argumentExpressions, returnByValue, generatePreview, awaitPromise)
{
var objectId;
var callArguments = [];
var promise = InspectorTest.sendCommandPromise("Runtime.evaluate", { expression: objectExpression })
.then((result) => objectId = result.result.result.objectId)
for (let argumentExpression of argumentExpressions) {
promise = promise
.then(() => InspectorTest.sendCommandPromise("Runtime.evaluate", { expression: argumentExpression }))
.then((result) => addArgument(result.result.result));
}
return promise.then(() => InspectorTest.sendCommandPromise("Runtime.callFunctionOn", { objectId: objectId, functionDeclaration: functionDeclaration, arguments: callArguments, returnByValue: returnByValue, generatePreview: generatePreview, awaitPromise: awaitPromise }));
function addArgument(result)
{
if (result.objectId) {
callArguments.push({ objectId: result.objectId });
} else if (result.value) {
callArguments.push({ value: result.value })
} else if (result.unserializableValue) {
callArguments.push({ unserializableValue: result.unserializableValue });
} else if (result.type === "undefined") {
callArguments.push({});
} else {
InspectorTest.log("Unexpected argument object:");
InspectorTest.logObject(result);
InspectorTest.completeTest();
}
}
}
function dumpResult(result)
{
if (result.exceptionDetails && result.exceptionDetails.scriptId)
result.exceptionDetails.scriptId = 0;
if (result.result && result.result.objectId)
result.result.objectId = "[ObjectId]";
if (result.exceptionDetails) {
result.exceptionDetails.exceptionId = 0;
result.exceptionDetails.exception.objectId = 0;
}
InspectorTest.logObject(result);
}
Tests that CommandLineAPI is presented only while evaluation.
{
result : {
description : 15
type : number
value : 15
}
}
{
result : {
description : 0
type : number
value : 0
}
}
setPropertyForMethod()
{
result : {
description : 14
type : number
value : 14
}
}
{
result : {
description : 0
type : number
value : 0
}
}
{
result : {
description : 42
type : number
value : 42
}
}
defineValuePropertyForMethod()
{
result : {
description : 14
type : number
value : 14
}
}
{
result : {
description : 0
type : number
value : 0
}
}
{
result : {
description : 42
type : number
value : 42
}
}
definePropertiesForMethod()
{
result : {
description : 14
type : number
value : 14
}
}
{
result : {
description : 0
type : number
value : 0
}
}
{
result : {
description : 42
type : number
value : 42
}
}
defineAccessorPropertyForMethod()
{
result : {
description : 14
type : number
value : 14
}
}
{
result : {
description : 0
type : number
value : 0
}
}
{
result : {
description : 42
type : number
value : 42
}
}
redefineGetOwnPropertyDescriptors()
{
result : {
description : 14
type : number
value : 14
}
}
{
result : {
description : 0
type : number
value : 0
}
}
{
result : {
description : 42
type : number
value : 42
}
}
// 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.
print("Tests that CommandLineAPI is presented only while evaluation.");
InspectorTest.evaluateInPage(
`
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(\\"[Command Line API]\\") !== -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)
{
var cb;
var p = new Promise(resolver => cb = resolver);
InspectorTest.sendCommandOrDie("Runtime.evaluate", { expression: expression, objectGroup: "console", includeCommandLineAPI: includeCommandLineAPI }, cb);
return p;
}
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.logObject(result));
}
function dumpLeftMethods()
{
// Should always be zero.
return setLastEvaluationResultTo239()
.then(() => evaluate("presentedAPIMethods()", false))
.then((result) => InspectorTest.logObject(result));
}
function dumpDir()
{
// Should always be presented.
return evaluate("dir", false)
.then((result) => InspectorTest.logObject(result));
}
Compiling script: foo1.js
persist: false
compilation result: {
exceptionDetails : {
columnNumber : 2
exception : {
className : SyntaxError
description : SyntaxError: Unexpected end of input
objectId : 0
subtype : error
type : object
}
exceptionId : 0
lineNumber : 1
scriptId : 0
text : Uncaught
}
}
-----
Compiling script: foo2.js
persist: true
Debugger.scriptParsed: foo2.js
compilation result: {
scriptId : 0
}
-----
Compiling script: foo3.js
persist: false
compilation result: {
}
-----
Compiling script: foo4.js
persist: false
compilation result: {
exceptionDetails : {
columnNumber : 13
exception : {
className : SyntaxError
description : SyntaxError: Unexpected identifier
objectId : 0
subtype : error
type : object
}
exceptionId : 0
lineNumber : 0
scriptId : 0
text : Uncaught
}
}
-----
// 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.
var executionContextId;
InspectorTest.sendCommand("Debugger.enable", {}, onDebuggerEnabled);
function onDebuggerEnabled()
{
InspectorTest.sendCommand("Runtime.enable", {});
InspectorTest.eventHandler["Debugger.scriptParsed"] = onScriptParsed;
InspectorTest.eventHandler["Runtime.executionContextCreated"] = 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);
var callback;
var promise = new Promise(resolver => callback = resolver);
InspectorTest.sendCommand("Runtime.compileScript", {
expression: expression,
sourceURL: sourceURL,
persistScript: persistScript,
executionContextId: executionContextId
}, onCompiled);
return promise;
function onCompiled(messageObject)
{
var result = messageObject.result;
if (result.exceptionDetails) {
result.exceptionDetails.exceptionId = 0;
result.exceptionDetails.exception.objectId = 0;
result.exceptionDetails.scriptId = 0;
}
if (result.scriptId)
result.scriptId = 0;
InspectorTest.logObject(result, "compilation result: ");
InspectorTest.log("-----");
callback();
}
}
Check that console.log is reported through Console domain as well.
api call: 42
api call: abc
console message: 42
console message: abc
// 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.
print("Check that console.log is reported through Console domain as well.");
var expectedMessages = 4;
var messages = [];
InspectorTest.eventHandler["Runtime.consoleAPICalled"] = consoleAPICalled;
InspectorTest.eventHandler["Console.messageAdded"] = messageAdded;
InspectorTest.sendCommandOrDie("Runtime.enable", {});
InspectorTest.sendCommandOrDie("Console.enable", {});
InspectorTest.sendCommandOrDie("Runtime.evaluate", { "expression": "console.log(42)" });
InspectorTest.sendCommandOrDie("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();
}
Tests checks that deprecation messages for console.
'console.timeline' is deprecated. Please use 'console.time' instead.
'console.timelineEnd' is deprecated. Please use 'console.timeEnd' instead.
'console.markTimeline' is deprecated. Please use 'console.timeStamp' instead.
// 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.
print("Tests checks that deprecation messages for console.")
InspectorTest.eventHandler["Runtime.consoleAPICalled"] = messageAdded;
InspectorTest.sendCommand("Runtime.enable", {});
var deprecatedMethods = [
"console.timeline(\"42\")",
"console.timeline(\"42\")",
"console.timeline(\"42\")", // three calls should produce one warning message
"console.timelineEnd(\"42\")",
"console.markTimeline(\"42\")",
];
InspectorTest.sendCommand("Runtime.evaluate", { expression: deprecatedMethods.join(";") });
var messagesLeft = 3;
function messageAdded(data)
{
var text = data.params.args[0].value;
if (text.indexOf("deprecated") === -1)
return;
InspectorTest.log(text);
if (!--messagesLeft)
InspectorTest.completeTest();
}
{
stackTrace : {
callFrames : [
[0] : {
columnNumber : 8
functionName : (anonymous)
lineNumber : 0
scriptId : 0
url : (empty)
}
]
}
type : log
}
{
stackTrace : {
callFrames : [
[0] : {
columnNumber : 2
functionName : (anonymous)
lineNumber : 1
scriptId : 0
url : (empty)
}
]
}
type : log
}
// 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.
InspectorTest.sendCommand("Runtime.enable", {});
addConsoleMessagePromise("console.log(239)")
.then(dumpMessage)
.then(() => addConsoleMessagePromise("var l = console.log;\n l(239)"))
.then(dumpMessage)
.then(() => InspectorTest.completeTest());
function addConsoleMessagePromise(expression)
{
var cb;
var p = new Promise((resolver) => cb = resolver);
InspectorTest.eventHandler["Runtime.consoleAPICalled"] = (messageObject) => cb(messageObject);
InspectorTest.sendCommand("Runtime.evaluate", { expression: expression });
return p;
}
function dumpMessage(messageObject)
{
var msg = messageObject.params;
delete msg.executionContextId;
delete msg.args;
delete msg.timestamp;
for (var frame of msg.stackTrace.callFrames)
frame.scriptId = 0;
if (!frame.functionName)
frame.functionName = "(anonymous)";
if (!frame.url)
frame.url = "(empty)";
InspectorTest.logObject(msg);
}
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
}
// 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.
print("Check that console.log doesn't run microtasks.");
InspectorTest.evaluateInPage(
`
function testFunction()
{
Promise.resolve().then(function(){ console.log(239); });
console.log(42);
console.log(43);
}`);
InspectorTest.sendCommandOrDie("Runtime.enable", {});
InspectorTest.eventHandler["Runtime.consoleAPICalled"] = messageAdded;
InspectorTest.sendCommandOrDie("Runtime.evaluate", { "expression": "testFunction()" });
InspectorTest.sendCommandOrDie("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();
}
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
// 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.
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();
}
InspectorTest.eventHandler["Runtime.consoleAPICalled"] = messageAdded;
InspectorTest.sendCommand("Runtime.enable", {});
InspectorTest.sendCommand("Runtime.evaluate", { expression: "console.log('testUnique'); for (var i = 0; i < 2; ++i) console.log('testDouble');" });
Tests that Runtime.evaluate works with awaitPromise flag.
Running test: testResolvedPromise
{
result : {
description : 239
type : number
value : 239
}
}
Running test: testRejectedPromise
{
exceptionDetails : {
columnNumber : 0
exception : {
description : 239
objectId : 0
type : number
value : 239
}
exceptionId : 0
lineNumber : 0
scriptId : (scriptId)
stackTrace : {
callFrames : [
]
}
text : Uncaught (in promise)
}
result : {
description : 239
type : number
value : 239
}
}
Running test: testPrimitiveValueInsteadOfPromise
{
code : -32000
message : Result of the evaluation is not a promise
}
Running test: testObjectInsteadOfPromise
{
code : -32000
message : Result of the evaluation is not a promise
}
Running test: testPendingPromise
{
result : {
type : object
value : {
a : 239
}
}
}
Running test: testExceptionInEvaluate
{
exceptionDetails : {
columnNumber : 0
exception : {
description : 239
objectId : 0
type : number
value : 239
}
exceptionId : 0
lineNumber : 0
scriptId : (scriptId)
text : Uncaught
}
result : {
description : 239
type : number
value : 239
}
}
// 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.
print("Tests that Runtime.evaluate works with awaitPromise flag.");
InspectorTest.evaluateInPage(`
function createPromiseAndScheduleResolve()
{
var resolveCallback;
var promise = new Promise((resolve) => resolveCallback = resolve);
setTimeout(resolveCallback.bind(null, { a : 239 }), 0);
return promise;
}`);
function dumpResult(result)
{
if (result.exceptionDetails) {
result.exceptionDetails.scriptId = "(scriptId)";
result.exceptionDetails.exceptionId = 0;
result.exceptionDetails.exception.objectId = 0;
}
InspectorTest.logObject(result);
}
InspectorTest.runTestSuite([
function testResolvedPromise(next)
{
InspectorTest.sendCommandPromise("Runtime.evaluate", { expression: "Promise.resolve(239)", awaitPromise: true, generatePreview: true })
.then((result) => dumpResult(result.result))
.then(() => next());
},
function testRejectedPromise(next)
{
InspectorTest.sendCommandPromise("Runtime.evaluate", { expression: "Promise.reject(239)", awaitPromise: true })
.then((result) => dumpResult(result.result))
.then(() => next());
},
function testPrimitiveValueInsteadOfPromise(next)
{
InspectorTest.sendCommandPromise("Runtime.evaluate", { expression: "true", awaitPromise: true })
.then((result) => InspectorTest.logObject(result.error))
.then(() => next());
},
function testObjectInsteadOfPromise(next)
{
InspectorTest.sendCommandPromise("Runtime.evaluate", { expression: "({})", awaitPromise: true })
.then((result) => InspectorTest.logObject(result.error))
.then(() => next());
},
function testPendingPromise(next)
{
InspectorTest.sendCommandPromise("Runtime.evaluate", { expression: "createPromiseAndScheduleResolve()", awaitPromise: true, returnByValue: true })
.then((result) => dumpResult(result.result))
.then(() => next());
},
function testExceptionInEvaluate(next)
{
InspectorTest.sendCommandPromise("Runtime.evaluate", { expression: "throw 239", awaitPromise: true })
.then((result) => dumpResult(result.result))
.then(() => next());
}
]);
Tests that DevTools doesn't crash on Runtime.evaluate with contextId equals 0.
{
error : {
code : -32000
message : Cannot find context with specified id
}
id : 0
}
// 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.
print("Tests that DevTools doesn't crash on Runtime.evaluate with contextId equals 0.");
InspectorTest.sendCommand("Runtime.evaluate", { "contextId": 0, "expression": "" }, evaluateCallback);
function evaluateCallback(result)
{
result.id = 0;
InspectorTest.logObject(result);
InspectorTest.completeTest();
}
Properties of Object(5)
__proto__ own object undefined
foo own string cat
Internal properties
[[PrimitiveValue]] number 5
Properties of Not own properties
__defineGetter__ inherited function undefined
__defineSetter__ inherited function undefined
__lookupGetter__ inherited function undefined
__lookupSetter__ inherited function undefined
__proto__ inherited no value, getter, setter
a own number 2
b own no value, getter, setter
c inherited number 4
constructor inherited function undefined
d inherited no value, getter
hasOwnProperty inherited function undefined
isPrototypeOf inherited function undefined
propertyIsEnumerable inherited function undefined
toLocaleString inherited function undefined
toString inherited function undefined
valueOf inherited function undefined
Properties of Accessor only properties
b own no value, getter, setter
d own no value, setter
Properties of array
0 own string red
1 own string green
2 own string blue
__proto__ own object undefined
length own number 3
Properties of Bound function
__proto__ own function undefined
length own number 0
name own string bound Number
Internal properties
[[BoundArgs]] object undefined
[[BoundThis]] object undefined
[[TargetFunction]] function undefined
Check that while Runtime.getProperties call on proxy object no user defined trap will be executed.
{
result : {
description : 0
type : number
value : 0
}
}
// 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.
print("Check that while Runtime.getProperties call on proxy object no user defined trap will be executed.");
InspectorTest.evaluateInPage(`
var self = this;
function testFunction()
{
self.counter = 0;
var handler = {
get: function(target, name){
self.counter++;
return Reflect.get.apply(this, arguments);
},
set: function(target, name){
self.counter++;
return Reflect.set.apply(this, arguments);
},
getPrototypeOf: function(target) {
self.counter++;
return Reflect.getPrototypeOf.apply(this, arguments);
},
setPrototypeOf: function(target) {
self.counter++;
return Reflect.setPrototypeOf.apply(this, arguments);
},
isExtensible: function(target) {
self.counter++;
return Reflect.isExtensible.apply(this, arguments);
},
isExtensible: function(target) {
self.counter++;
return Reflect.isExtensible.apply(this, arguments);
},
isExtensible: function(target) {
self.counter++;
return Reflect.isExtensible.apply(this, arguments);
},
preventExtensions: function() {
self.counter++;
return Reflect.preventExtensions.apply(this, arguments);
},
getOwnPropertyDescriptor: function() {
self.counter++;
return Reflect.getOwnPropertyDescriptor.apply(this, arguments);
},
defineProperty: function() {
self.counter++;
return Reflect.defineProperty.apply(this, arguments);
},
has: function() {
self.counter++;
return Reflect.has.apply(this, arguments);
},
get: function() {
self.counter++;
return Reflect.get.apply(this, arguments);
},
set: function() {
self.counter++;
return Reflect.set.apply(this, arguments);
},
deleteProperty: function() {
self.counter++;
return Reflect.deleteProperty.apply(this, arguments);
},
ownKeys: function() {
self.counter++;
return Reflect.ownKeys.apply(this, arguments);
},
apply: function() {
self.counter++;
return Reflect.apply.apply(this, arguments);
},
construct: function() {
self.counter++;
return Reflect.construct.apply(this, arguments);
}
};
return new Proxy({ a : 1}, handler);
}`);
InspectorTest.sendCommandOrDie("Runtime.evaluate", { expression: "testFunction()"}, requestProperties);
function requestProperties(result)
{
InspectorTest.sendCommandOrDie("Runtime.getProperties", { objectId: result.result.objectId, generatePreview: true }, checkCounter);
}
function checkCounter(result)
{
InspectorTest.sendCommandOrDie("Runtime.evaluate", { expression: "self.counter" }, dumpCounter);
}
function dumpCounter(result)
{
InspectorTest.logObject(result);
InspectorTest.completeTest();
}
p1 : Object
p2 : Object
p1 : {
"type": "object",
"description": "Object",
"overflow": false,
"properties": [
{
"name": "a",
"type": "number",
"value": "1"
}
]
}
p2 : {
"type": "object",
"description": "Object",
"overflow": false,
"properties": [
{
"name": "b",
"type": "string",
"value": "foo"
},
{
"name": "bb",
"type": "string",
"value": "bar"
}
]
}
// 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.
InspectorTest.sendCommand("Runtime.evaluate", { "expression": "({p1: {a:1}, p2: {b:'foo', bb:'bar'}})" }, callbackEvaluate);
function callbackEvaluate(result)
{
InspectorTest.sendCommand("Runtime.getProperties", { "objectId": result.result.result.objectId, "ownProperties": true }, callbackGetProperties.bind(null, false));
InspectorTest.sendCommand("Runtime.getProperties", { "objectId": result.result.result.objectId, "ownProperties": true, "generatePreview": true }, callbackGetProperties.bind(null, true));
}
function callbackGetProperties(completeTest, result)
{
for (var property of result.result.result) {
if (!property.value || property.name === "__proto__")
continue;
if (property.value.preview)
InspectorTest.log(property.name + " : " + JSON.stringify(property.value.preview, null, 4));
else
InspectorTest.log(property.name + " : " + property.value.description);
}
if (completeTest)
InspectorTest.completeTest();
}
// 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.
// A general-purpose engine for sending a sequence of protocol commands.
// The clients provide requests and response handlers, while the engine catches
// errors and makes sure that once there's nothing to do completeTest() is called.
// @param step is an object with command, params and callback fields
function runRequestSeries(step)
{
processStep(step);
function processStep(s)
{
try {
processStepOrFail(s);
} catch (e) {
InspectorTest.log(e.stack);
InspectorTest.completeTest();
}
}
function processStepOrFail(s)
{
if (!s) {
InspectorTest.completeTest();
return;
}
if (!s.command) {
// A simple loopback step.
var next = s.callback();
processStep(next);
return;
}
var innerCallback = function(response)
{
if ("error" in response) {
InspectorTest.log(response.error.message);
InspectorTest.completeTest();
return;
}
var next;
try {
next = s.callback(response.result);
} catch (e) {
InspectorTest.log(e.stack);
InspectorTest.completeTest();
return;
}
processStep(next);
}
InspectorTest.sendCommand(s.command, s.params, innerCallback);
}
}
var firstStep = { callback: callbackStart5 };
runRequestSeries(firstStep);
// 'Object5' section -- check properties of '5' wrapped as object (has an internal property).
function callbackStart5()
{
// Create an wrapper object with additional property.
var expression = "(function(){var r = Object(5); r.foo = 'cat';return r;})()";
return { command: "Runtime.evaluate", params: {expression: expression}, callback: callbackEval5 };
}
function callbackEval5(result)
{
var id = result.result.objectId;
if (id === undefined)
throw new Error("objectId is expected");
return {
command: "Runtime.getProperties", params: {objectId: id, ownProperties: true}, callback: callbackProperties5
};
}
function callbackProperties5(result)
{
logGetPropertiesResult("Object(5)", result);
return { callback: callbackStartNotOwn };
}
// 'Not own' section -- check all properties of the object, including ones from it prototype chain.
function callbackStartNotOwn()
{
// Create an wrapper object with additional property.
var expression = "({ a: 2, set b(_) {}, get b() {return 5;}, __proto__: { a: 3, c: 4, get d() {return 6;} }})";
return { command: "Runtime.evaluate", params: {expression: expression}, callback: callbackEvalNotOwn };
}
function callbackEvalNotOwn(result)
{
var id = result.result.objectId;
if (id === undefined)
throw new Error("objectId is expected");
return {
command: "Runtime.getProperties", params: {objectId: id, ownProperties: false}, callback: callbackPropertiesNotOwn
};
}
function callbackPropertiesNotOwn(result)
{
logGetPropertiesResult("Not own properties", result);
return { callback: callbackStartAccessorsOnly };
}
// 'Accessors only' section -- check only accessor properties of the object.
function callbackStartAccessorsOnly()
{
// Create an wrapper object with additional property.
var expression = "({ a: 2, set b(_) {}, get b() {return 5;}, c: 'c', set d(_){} })";
return { command: "Runtime.evaluate", params: {expression: expression}, callback: callbackEvalAccessorsOnly };
}
function callbackEvalAccessorsOnly(result)
{
var id = result.result.objectId;
if (id === undefined)
throw new Error("objectId is expected");
return {
command: "Runtime.getProperties", params: {objectId: id, ownProperties: true, accessorPropertiesOnly: true}, callback: callbackPropertiesAccessorsOnly
};
}
function callbackPropertiesAccessorsOnly(result)
{
logGetPropertiesResult("Accessor only properties", result);
return { callback: callbackStartArray };
}
// 'Array' section -- check properties of an array.
function callbackStartArray()
{
var expression = "['red', 'green', 'blue']";
return { command: "Runtime.evaluate", params: {expression: expression}, callback: callbackEvalArray };
}
function callbackEvalArray(result)
{
var id = result.result.objectId;
if (id === undefined)
throw new Error("objectId is expected");
return {
command: "Runtime.getProperties", params: {objectId: id, ownProperties: true}, callback: callbackPropertiesArray
};
}
function callbackPropertiesArray(result)
{
logGetPropertiesResult("array", result);
return { callback: callbackStartBound };
}
// 'Bound' section -- check properties of a bound function (has a bunch of internal properties).
function callbackStartBound()
{
var expression = "Number.bind({}, 5)";
return { command: "Runtime.evaluate", params: {expression: expression}, callback: callbackEvalBound };
}
function callbackEvalBound(result)
{
var id = result.result.objectId;
if (id === undefined)
throw new Error("objectId is expected");
return {
command: "Runtime.getProperties", params: {objectId: id, ownProperties: true}, callback: callbackPropertiesBound
};
}
function callbackPropertiesBound(result)
{
logGetPropertiesResult("Bound function", result);
return; // End of test
}
// A helper function that dumps object properties and internal properties in sorted order.
function logGetPropertiesResult(title, protocolResult)
{
function hasGetterSetter(property, fieldName)
{
var v = property[fieldName];
if (!v)
return false;
return v.type !== "undefined"
}
InspectorTest.log("Properties of " + title);
var propertyArray = protocolResult.result;
propertyArray.sort(NamedThingComparator);
for (var i = 0; i < propertyArray.length; i++) {
var p = propertyArray[i];
var v = p.value;
var own = p.isOwn ? "own" : "inherited";
if (v)
InspectorTest.log(" " + p.name + " " + own + " " + v.type + " " + v.value);
else
InspectorTest.log(" " + p.name + " " + own + " no value" +
(hasGetterSetter(p, "get") ? ", getter" : "") + (hasGetterSetter(p, "set") ? ", setter" : ""));
}
var internalPropertyArray = protocolResult.internalProperties;
if (internalPropertyArray) {
InspectorTest.log("Internal properties");
internalPropertyArray.sort(NamedThingComparator);
for (var i = 0; i < internalPropertyArray.length; i++) {
var p = internalPropertyArray[i];
var v = p.value;
InspectorTest.log(" " + p.name + " " + v.type + " " + v.value);
}
}
function NamedThingComparator(o1, o2)
{
return o1.name === o2.name ? 0 : (o1.name < o2.name ? -1 : 1);
}
}
Tests that property defined on console.__proto__ doesn't observable on other Objects.
{
id : 0
result : {
result : {
description : 0
type : number
value : 0
}
}
}
// 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.
print("Tests that property defined on console.__proto__ doesn't observable on other Objects.");
InspectorTest.evaluateInPage(`
function testFunction()
{
var amountOfProperties = 0;
for (var p in {})
++amountOfProperties;
console.__proto__.debug = 239;
for (var p in {})
--amountOfProperties;
return amountOfProperties;
}`);
InspectorTest.sendCommand("Runtime.evaluate", { "expression": "testFunction()" }, dumpResult);
function dumpResult(result)
{
result.id = 0;
InspectorTest.logObject(result);
InspectorTest.completeTest();
}
Tests that Runtime.compileScript and Runtime.runScript work with awaitPromise flag.
Running test: testRunAndCompileWithoutAgentEnable
{
code : 0
message : Runtime agent is not enabled
}
{
code : 0
message : Runtime agent is not enabled
}
Running test: testSyntaxErrorInScript
{
exceptionDetails : {
columnNumber : 1
exception : {
className : SyntaxError
description : SyntaxError: Unexpected token }
objectId : 0
subtype : error
type : object
}
exceptionId : 0
lineNumber : 1
scriptId : 0
text : Uncaught
}
}
Running test: testSyntaxErrorInEvalInScript
{
exceptionDetails : {
columnNumber : 0
exception : {
className : SyntaxError
description : SyntaxError: Unexpected token } at boo.js:2:2
objectId : 0
subtype : error
type : object
}
exceptionId : 0
lineNumber : 0
scriptId : 0
stackTrace : {
callFrames : [
[0] : {
columnNumber : 1
functionName :
lineNumber : 1
scriptId : 0
url : boo.js
}
]
}
text : Uncaught
}
result : {
className : SyntaxError
description : SyntaxError: Unexpected token } at boo.js:2:2
objectId : [ObjectId]
subtype : error
type : object
}
}
Running test: testRunNotCompiledScript
{
code : 0
message : No script with given id
}
Running test: testRunCompiledScriptAfterAgentWasReenabled
{
code : 0
message : Runtime agent is not enabled
}
{
code : 0
message : No script with given id
}
Running test: testRunScriptWithPreview
{
result : {
className : Object
description : Object
objectId : [ObjectId]
preview : {
description : Object
overflow : false
properties : [
[0] : {
name : a
type : number
value : 1
}
]
type : object
}
type : object
}
}
Running test: testRunScriptReturnByValue
{
result : {
type : object
value : {
a : 1
}
}
}
Running test: testAwaitNotPromise
{
code : 0
message : Result of the script execution is not a promise
}
Running test: testAwaitResolvedPromise
{
result : {
type : object
value : {
a : 1
}
}
}
Running test: testAwaitRejectedPromise
{
exceptionDetails : {
columnNumber : 0
exception : {
objectId : 0
type : object
value : {
a : 1
}
}
exceptionId : 0
lineNumber : 0
stackTrace : {
callFrames : [
]
}
text : Uncaught (in promise)
}
result : {
type : object
value : {
a : 1
}
}
}
// 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.
print("Tests that Runtime.compileScript and Runtime.runScript work with awaitPromise flag.");
InspectorTest.runTestSuite([
function testRunAndCompileWithoutAgentEnable(next)
{
InspectorTest.sendCommandPromise("Runtime.compileScript", { expression: "", sourceURL: "", persistScript: true })
.then((result) => dumpResult(result))
.then(() => InspectorTest.sendCommandPromise("Runtime.runScript", { scriptId: "1" }))
.then((result) => dumpResult(result))
.then(() => next());
},
function testSyntaxErrorInScript(next)
{
InspectorTest.sendCommandPromise("Runtime.enable", {})
.then(() => InspectorTest.sendCommandPromise("Runtime.compileScript", { expression: "\n }", sourceURL: "boo.js", persistScript: true }))
.then((result) => dumpResult(result))
.then(() => InspectorTest.sendCommandPromise("Runtime.disable", {}))
.then(() => next());
},
function testSyntaxErrorInEvalInScript(next)
{
InspectorTest.sendCommandPromise("Runtime.enable", {})
.then(() => InspectorTest.sendCommandPromise("Runtime.compileScript", { expression: "{\n eval(\"\\\n}\")\n}", sourceURL: "boo.js", persistScript: true }))
.then((result) => InspectorTest.sendCommandPromise("Runtime.runScript", { scriptId: result.result.scriptId }))
.then((result) => dumpResult(result))
.then(() => InspectorTest.sendCommandPromise("Runtime.disable", {}))
.then(() => next());
},
function testRunNotCompiledScript(next)
{
InspectorTest.sendCommandPromise("Runtime.enable", {})
.then((result) => InspectorTest.sendCommandPromise("Runtime.runScript", { scriptId: "1" }))
.then((result) => dumpResult(result))
.then(() => InspectorTest.sendCommandPromise("Runtime.disable", {}))
.then(() => next());
},
function testRunCompiledScriptAfterAgentWasReenabled(next)
{
var scriptId;
InspectorTest.sendCommandPromise("Runtime.enable", {})
.then(() => InspectorTest.sendCommandPromise("Runtime.compileScript", { expression: "{\n eval(\"\\\n}\")\n}", sourceURL: "boo.js", persistScript: true }))
.then((result) => scriptId = result.result.scriptId)
.then(() => InspectorTest.sendCommandPromise("Runtime.disable", {}))
.then((result) => InspectorTest.sendCommandPromise("Runtime.runScript", { scriptId: scriptId }))
.then((result) => dumpResult(result))
.then(() => InspectorTest.sendCommandPromise("Runtime.enable", {}))
.then((result) => InspectorTest.sendCommandPromise("Runtime.runScript", { scriptId: scriptId }))
.then((result) => dumpResult(result))
.then(() => InspectorTest.sendCommandPromise("Runtime.disable", {}))
.then(() => next());
},
function testRunScriptWithPreview(next)
{
InspectorTest.sendCommandPromise("Runtime.enable", {})
.then(() => InspectorTest.sendCommandPromise("Runtime.compileScript", { expression: "({a:1})", sourceURL: "boo.js", persistScript: true }))
.then((result) => InspectorTest.sendCommandPromise("Runtime.runScript", { scriptId: result.result.scriptId, generatePreview: true }))
.then((result) => dumpResult(result))
.then(() => InspectorTest.sendCommandPromise("Runtime.disable", {}))
.then(() => next());
},
function testRunScriptReturnByValue(next)
{
InspectorTest.sendCommandPromise("Runtime.enable", {})
.then(() => InspectorTest.sendCommandPromise("Runtime.compileScript", { expression: "({a:1})", sourceURL: "boo.js", persistScript: true }))
.then((result) => InspectorTest.sendCommandPromise("Runtime.runScript", { scriptId: result.result.scriptId, returnByValue: true }))
.then((result) => dumpResult(result))
.then(() => InspectorTest.sendCommandPromise("Runtime.disable", {}))
.then(() => next());
},
function testAwaitNotPromise(next)
{
InspectorTest.sendCommandPromise("Runtime.enable", {})
.then(() => InspectorTest.sendCommandPromise("Runtime.compileScript", { expression: "({a:1})", sourceURL: "boo.js", persistScript: true }))
.then((result) => InspectorTest.sendCommandPromise("Runtime.runScript", { scriptId: result.result.scriptId, awaitPromise: true }))
.then((result) => dumpResult(result))
.then(() => InspectorTest.sendCommandPromise("Runtime.disable", {}))
.then(() => next());
},
function testAwaitResolvedPromise(next)
{
InspectorTest.sendCommandPromise("Runtime.enable", {})
.then(() => InspectorTest.sendCommandPromise("Runtime.compileScript", { expression: "Promise.resolve({a:1})", sourceURL: "boo.js", persistScript: true }))
.then((result) => InspectorTest.sendCommandPromise("Runtime.runScript", { scriptId: result.result.scriptId, awaitPromise: true, returnByValue: true }))
.then((result) => dumpResult(result))
.then(() => InspectorTest.sendCommandPromise("Runtime.disable", {}))
.then(() => next());
},
function testAwaitRejectedPromise(next)
{
InspectorTest.sendCommandPromise("Runtime.enable", {})
.then(() => InspectorTest.sendCommandPromise("Runtime.compileScript", { expression: "Promise.reject({a:1})", sourceURL: "boo.js", persistScript: true }))
.then((result) => InspectorTest.sendCommandPromise("Runtime.runScript", { scriptId: result.result.scriptId, awaitPromise: true, returnByValue: true }))
.then((result) => dumpResult(result))
.then(() => InspectorTest.sendCommandPromise("Runtime.disable", {}))
.then(() => next());
}
]);
function dumpResult(result)
{
if (result.error) {
result.error.code = 0;
InspectorTest.logObject(result.error);
return;
}
result = result.result;
if (result.exceptionDetails) {
result.exceptionDetails.exceptionId = 0;
result.exceptionDetails.exception.objectId = 0;
}
if (result.exceptionDetails && result.exceptionDetails.scriptId)
result.exceptionDetails.scriptId = 0;
if (result.exceptionDetails && result.exceptionDetails.stackTrace) {
for (var frame of result.exceptionDetails.stackTrace.callFrames)
frame.scriptId = 0;
}
if (result.result && result.result.objectId)
result.result.objectId = "[ObjectId]";
InspectorTest.logObject(result);
}
......@@ -132,3 +132,6 @@ void ExecuteStringTask::Run(v8::Isolate* isolate,
v8::MaybeLocal<v8::Value> result;
result = script->Run(local_context);
}
// main to make compiler happy before other patch will be landed.
int main(int argc, char* argv[]) { return 0; }
# 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.
import itertools
import os
import re
from testrunner.local import testsuite
from testrunner.local import utils
from testrunner.objects import testcase
FLAGS_PATTERN = re.compile(r"//\s+Flags:(.*)")
PROTOCOL_TEST_JS = "protocol-test.js"
EXPECTED_SUFFIX = "-expected.txt"
class InspectorProtocolTestSuite(testsuite.TestSuite):
def __init__(self, name, root):
super(InspectorProtocolTestSuite, self).__init__(name, root)
def ListTests(self, context):
tests = []
for dirname, dirs, files in os.walk(os.path.join(self.root), followlinks=True):
for dotted in [x for x in dirs if x.startswith('.')]:
dirs.remove(dotted)
dirs.sort()
files.sort()
for filename in files:
if filename.endswith(".js") and filename != PROTOCOL_TEST_JS:
fullpath = os.path.join(dirname, filename)
relpath = fullpath[len(self.root) + 1 : -3]
testname = relpath.replace(os.path.sep, "/")
test = testcase.TestCase(self, testname)
tests.append(test)
return tests
def GetFlagsForTestCase(self, testcase, context):
source = self.GetSourceForTest(testcase)
flags_match = re.findall(FLAGS_PATTERN, source)
flags = []
for match in flags_match:
flags += match.strip().split()
testname = testcase.path.split(os.path.sep)[-1]
testfilename = os.path.join(self.root, testcase.path + self.suffix())
protocoltestfilename = os.path.join(self.root, PROTOCOL_TEST_JS)
return [ protocoltestfilename, testfilename ] + flags
def GetSourceForTest(self, testcase):
filename = os.path.join(self.root, testcase.path + self.suffix())
with open(filename) as f:
return f.read()
def shell(self):
return "inspector-test"
def _IgnoreLine(self, string):
"""Ignore empty lines, valgrind output and Android output."""
if not string: return True
return (string.startswith("==") or string.startswith("**") or
string.startswith("ANDROID") or
# FIXME(machenbach): The test driver shouldn't try to use slow
# asserts if they weren't compiled. This fails in optdebug=2.
string == "Warning: unknown flag --enable-slow-asserts." or
string == "Try --help for options")
def IsFailureOutput(self, testcase):
file_name = os.path.join(self.root, testcase.path) + EXPECTED_SUFFIX
with file(file_name, "r") as expected:
expected_lines = expected.readlines()
def ExpIterator():
for line in expected_lines:
if line.startswith("#") or not line.strip(): continue
yield line.strip()
def ActIterator(lines):
for line in lines:
if self._IgnoreLine(line.strip()): continue
yield line.strip()
def ActBlockIterator():
"""Iterates over blocks of actual output lines."""
lines = testcase.output.stdout.splitlines()
start_index = 0
found_eqeq = False
for index, line in enumerate(lines):
# If a stress test separator is found:
if line.startswith("=="):
# Iterate over all lines before a separator except the first.
if not found_eqeq:
found_eqeq = True
else:
yield ActIterator(lines[start_index:index])
# The next block of output lines starts after the separator.
start_index = index + 1
# Iterate over complete output if no separator was found.
if not found_eqeq:
yield ActIterator(lines)
for act_iterator in ActBlockIterator():
for (expected, actual) in itertools.izip_longest(
ExpIterator(), act_iterator, fillvalue=''):
if expected != actual:
return True
return False
def GetSuite(name, root):
return InspectorProtocolTestSuite(name, root)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment