Commit 65423b1d authored by dgozman's avatar dgozman Committed by Commit Bot

[DevTools] Migrate inspector-protocol/{timeline,worker} tests to new harness

BUG=734762

Review-Url: https://codereview.chromium.org/2953663003
Cr-Commit-Position: refs/heads/master@{#481726}
parent 5f2725f6
......@@ -2660,8 +2660,8 @@ Bug(none) inspector-protocol/heap-profiler/heap-snapshot-with-event-listener.htm
Bug(none) inspector-protocol/layout-fonts/unicode-range-combining-chars-fallback.html [ Failure ]
Bug(none) inspector-protocol/network/resource-type.html [ Timeout ]
Bug(none) inspector-protocol/network/websocket-initiator.html [ Timeout ]
Bug(none) inspector-protocol/worker/exception-from-worker-contains-stack.html [ Timeout ]
Bug(none) inspector-protocol/worker/worker-console.html [ Timeout ]
Bug(none) inspector-protocol/worker/exception-from-worker-contains-stack.js [ Timeout ]
Bug(none) inspector-protocol/worker/worker-console.js [ Timeout ]
Bug(none) inspector/agents-enable-disable.html [ Timeout ]
Bug(none) inspector/animation/animation-KeyframeEffectReadOnly-crash.html [ Timeout ]
Bug(none) inspector/animation/animation-group-matching-animations.html [ Timeout ]
......
......@@ -2,135 +2,117 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
var evalCallbackCallId = 3;
(class TracingHelper {
constructor(testRunner, session) {
this._testRunner = testRunner;
this._session = session;
}
initialize_tracingHarness = function()
{
startTracing() {
return this.startTracingWithArguments({ "categories": "-*,disabled-by-default-devtools.timeline,devtools.timeline", "type": "", "options": "" });
}
InspectorTest.startTracing = function(callback)
{
InspectorTest.startTracingWithArguments({ "categories": "-*,disabled-by-default-devtools.timeline,devtools.timeline", "type": "", "options": "" }, callback);
}
InspectorTest.startTracingAndSaveAsStream = function(callback)
{
startTracingAndSaveAsStream() {
var args = {
"categories": "-*,disabled-by-default-devtools.timeline,devtools.timeline",
"type": "",
"options": "",
"transferMode": "ReturnAsStream"
"categories": "-*,disabled-by-default-devtools.timeline,devtools.timeline",
"type": "",
"options": "",
"transferMode": "ReturnAsStream"
};
InspectorTest.startTracingWithArguments(args, callback);
}
InspectorTest.startTracingWithArguments = function(args, callback)
{
InspectorTest.sendCommand("Tracing.start", args, onStart);
function onStart(response)
{
InspectorTest.log("Recording started");
callback();
}
}
InspectorTest.stopTracing = function(callback)
{
InspectorTest.eventHandler["Tracing.tracingComplete"] = tracingComplete;
InspectorTest.eventHandler["Tracing.dataCollected"] = dataCollected;
InspectorTest.sendCommand("Tracing.end", { });
InspectorTest.devtoolsEvents = [];
function dataCollected(reply)
{
var allEvents = reply.params.value;
InspectorTest.devtoolsEvents = InspectorTest.devtoolsEvents.concat(allEvents.filter(function(e)
{
return /devtools.timeline/.test(e.cat);
}));
}
function tracingComplete(event)
{
InspectorTest.log("Tracing complete");
InspectorTest.eventHandler["Tracing.tracingComplete"] = null;
InspectorTest.eventHandler["Tracing.dataCollected"] = null;
callback(InspectorTest.devtoolsEvents);
}
}
return this.startTracingWithArguments(args);
}
InspectorTest.stopTracingAndReturnStream = function(callback)
{
InspectorTest.eventHandler["Tracing.tracingComplete"] = tracingComplete;
InspectorTest.eventHandler["Tracing.dataCollected"] = dataCollected;
InspectorTest.sendCommand("Tracing.end");
async startTracingWithArguments(args) {
await this._session.protocol.Tracing.start(args);
this._testRunner.log("Recording started");
}
function dataCollected(reply)
{
InspectorTest.log("FAIL: dataCollected event should not be fired when returning trace as stream.");
async stopTracing() {
var devtoolsEvents = [];
}
function dataCollected(reply) {
var allEvents = reply.params.value;
var filteredEvents = allEvents.filter(e => /devtools.timeline/.test(e.cat));
devtoolsEvents = devtoolsEvents.concat(filteredEvents);
};
function tracingComplete(event)
{
InspectorTest.log("Tracing complete");
InspectorTest.eventHandler["Tracing.tracingComplete"] = null;
InspectorTest.eventHandler["Tracing.dataCollected"] = null;
callback(event.params.stream);
this._session.protocol.Tracing.onDataCollected(dataCollected);
this._session.protocol.Tracing.end();
await this._session.protocol.Tracing.onceTracingComplete();
this._testRunner.log("Tracing complete");
this._session.protocol.Tracing.offDataCollected(dataCollected);
this._devtoolsEvents = devtoolsEvents;
return devtoolsEvents;
}
async stopTracingAndReturnStream() {
function dataCollected() {
this._testRunner.log("FAIL: dataCollected event should not be fired when returning trace as stream.");
}
}
InspectorTest.retrieveStream = function(streamHandle, offset, chunkSize, callback)
{
this._session.protocol.Tracing.onDataCollected(dataCollected);
this._session.protocol.Tracing.end();
var event = await this._session.protocol.Tracing.onceTracingComplete();
this._testRunner.log("Tracing complete");
this._session.protocol.Tracing.offDataCollected(dataCollected);
return event.params.stream;
}
retrieveStream(streamHandle, offset, chunkSize) {
var callback;
var promise = new Promise(f => callback = f);
var result = "";
var had_eof = false;
var readArguments = { handle: streamHandle };
if (typeof chunkSize === "number")
readArguments.size = chunkSize;
readArguments.size = chunkSize;
var firstReadArguments = JSON.parse(JSON.stringify(readArguments));
if (typeof offset === "number")
firstReadArguments.offset = 0;
InspectorTest.sendCommandOrDie("IO.read", firstReadArguments, onChunkRead);
// Assure multiple in-lfight reads are fine (also, save on latencies).
InspectorTest.sendCommandOrDie("IO.read", readArguments, onChunkRead);
function onChunkRead(response)
{
if (had_eof)
return;
result += response.data;
if (response.eof) {
// Ignore stray callbacks from proactive read requests.
had_eof = true;
callback(result);
return;
}
InspectorTest.sendCommandOrDie("IO.read", readArguments, onChunkRead);
firstReadArguments.offset = 0;
this._session.protocol.IO.read(firstReadArguments).then(message => onChunkRead.call(this, message.result));
// Assure multiple in-flight reads are fine (also, save on latencies).
this._session.protocol.IO.read(readArguments).then(message => onChunkRead.call(this, message.result));
return promise;
function onChunkRead(response) {
if (had_eof)
return;
result += response.data;
if (response.eof) {
// Ignore stray callbacks from proactive read requests.
had_eof = true;
callback(result);
return;
}
this._session.protocol.IO.read(readArguments).then(message => onChunkRead.call(this, message.result));
}
}
}
InspectorTest.findEvents = function(name, ph, condition)
{
return InspectorTest.devtoolsEvents.filter(e => e.name === name && e.ph === ph && (!condition || condition(e)));
}
findEvents(name, ph, condition) {
return this._devtoolsEvents.filter(e => e.name === name && e.ph === ph && (!condition || condition(e)));
}
InspectorTest.findEvent = function(name, ph, condition)
{
var events = InspectorTest.findEvents(name, ph, condition);
findEvent(name, ph, condition) {
var events = this.findEvents(name, ph, condition);
if (events.length)
return events[0];
throw new Error("Couldn't find event " + name + " / " + ph + "\n\n in " + JSON.stringify(InspectorTest.devtoolsEvents, null, 2));
}
InspectorTest.invokeAsyncWithTracing = function(functionName, callback)
{
InspectorTest.startTracing(onStart);
function onStart()
{
InspectorTest.evaluateInPageAsync(functionName + "()").then((data) => InspectorTest.stopTracing((devtoolsEvents) => callback(devtoolsEvents, data)));
}
}
}
return events[0];
throw new Error("Couldn't find event " + name + " / " + ph + "\n\n in " + JSON.stringify(this.devtoolsEvents, null, 2));
}
filterEvents(callback) {
return this._devtoolsEvents.filter(callback);
}
async invokeAsyncWithTracing(performActions) {
await this.startTracing();
var data = await this._session.evaluateAsync(`(${performActions.toString()})()`);
await this.stopTracing();
return data;
}
formattedEvents() {
var formattedEvents = this._devtoolsEvents.map(e => e.name + (e.args.data ? '(' + e.args.data.type + ')' : ''));
return JSON.stringify(formattedEvents, null, 2);
}
})
Recording started
Tracing complete
Error after legit close: undefined
......
<html>
<head>
<style>
div#test {
display: none;
background-color: blue;
width: 100px;
height: 100px;
}
</style>
<script type="text/javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script>
<script type="text/javascript" src="../resources/tracing-test.js"></script>
<script>
function performActions()
{
var element = document.getElementById("test");
element.style.display = "block";
var unused = element.clientWidth;
}
function test()
{
InspectorTest.startTracingAndSaveAsStream(onStart);
function onStart()
{
InspectorTest.evaluateInPage("performActions()", evalDone);
}
function evalDone()
{
InspectorTest.stopTracingAndReturnStream(onStop);
}
function onStop(streamHandle)
{
var data1;
InspectorTest.retrieveStream(streamHandle, null, null, onGotStream1);
function onGotStream1(data)
{
data1 = data;
InspectorTest.retrieveStream(streamHandle, 0, 1000, onGotStream2);
}
function onGotStream2(data)
{
if (data1 !== data)
InspectorTest.log("FAIL: got different data for cunked vs. non-chunked reads");
InspectorTest.sendCommandOrDie("IO.close", { handle: streamHandle }, onCloseDone);
}
function onCloseDone(response)
{
InspectorTest.log("Error after legit close: " + JSON.stringify(response.error));
InspectorTest.sendCommand("IO.read", { handle: streamHandle }, onReadAfterClose);
}
function onReadAfterClose(response)
{
InspectorTest.log("Error after illegal read: " + JSON.stringify(response.error));
InspectorTest.sendCommand("IO.close", { handle: streamHandle }, onCloseAfterClose);
}
function onCloseAfterClose(response)
{
InspectorTest.log("Error after illegal close: " + JSON.stringify(response.error));
var trace = JSON.parse(data1);
performEventsSanityCheck(trace["traceEvents"]);
InspectorTest.log("Metadata: " + typeof trace["metadata"] + (trace["metadata"] ? ", not null" : ""));
InspectorTest.completeTest();
}
}
function assertGreaterOrEqual(a, b, message)
{
if (a >= b)
return;
InspectorTest.log(message + " (" + a + " < " + b + ")");
InspectorTest.completeTest();
}
function performEventsSanityCheck(events)
{
var phaseComplete = 0;
var knownEvents = {
"MessageLoop::PostTask": 0,
"FunctionCall": 0,
"UpdateLayoutTree": 0,
"Layout": 0
};
for (var i = 0; i < events.length; ++i) {
var event = events[i];
if (event.phase === "X")
++phaseComplete;
if (event.name in knownEvents)
++knownEvents[event.name];
}
assertGreaterOrEqual(events.length, 10, "Too few trace events recorded");
assertGreaterOrEqual(knownEvents["UpdateLayoutTree"], 1, "Too few UpdateLayoutTree events");
assertGreaterOrEqual(knownEvents["Layout"], 1, "Too few Layout events");
InspectorTest.log("Event sanity test done");
}
}
</script>
</head>
<body onload="runTest()">
<div id="test">
</div>
</body>
</html>
(async function(testRunner) {
let {page, session, dp} = await testRunner.startHTML(`
<style>
div#test {
display: none;
background-color: blue;
width: 100px;
height: 100px;
}
</style>
<div id='test'>
</div>
`, '');
var TracingHelper = await testRunner.loadScript('../resources/tracing-test.js');
var tracingHelper = new TracingHelper(testRunner, session);
await tracingHelper.startTracingAndSaveAsStream();
await session.evaluate(`
(function performActions() {
var element = document.getElementById('test');
element.style.display = 'block';
var unused = element.clientWidth;
})();
`);
var streamHandle = await tracingHelper.stopTracingAndReturnStream();
var data1 = await tracingHelper.retrieveStream(streamHandle, null, null);
var data2 = await tracingHelper.retrieveStream(streamHandle, 0, 1000);
if (data1 !== data2)
testRunner.log('FAIL: got different data for cunked vs. non-chunked reads');
var response = await dp.IO.close({ handle: streamHandle });
testRunner.log('Error after legit close: ' + JSON.stringify(response.error));
response = await dp.IO.read({ handle: streamHandle });
testRunner.log('Error after illegal read: ' + JSON.stringify(response.error));
response = await dp.IO.close({ handle: streamHandle });
testRunner.log('Error after illegal close: ' + JSON.stringify(response.error));
var trace = JSON.parse(data1);
performEventsSanityCheck(trace['traceEvents']);
testRunner.log('Metadata: ' + typeof trace['metadata'] + (trace['metadata'] ? ', not null' : ''));
testRunner.completeTest();
function assertGreaterOrEqual(a, b, message) {
if (a >= b)
return;
testRunner.log(message + ' (' + a + ' < ' + b + ')');
testRunner.completeTest();
}
function performEventsSanityCheck(events) {
var phaseComplete = 0;
var knownEvents = {
'MessageLoop::PostTask': 0,
'FunctionCall': 0,
'UpdateLayoutTree': 0,
'Layout': 0
};
for (var i = 0; i < events.length; ++i) {
var event = events[i];
if (event.phase === 'X')
++phaseComplete;
if (event.name in knownEvents)
++knownEvents[event.name];
}
assertGreaterOrEqual(events.length, 10, 'Too few trace events recorded');
assertGreaterOrEqual(knownEvents['UpdateLayoutTree'], 1, 'Too few UpdateLayoutTree events');
assertGreaterOrEqual(knownEvents['Layout'], 1, 'Too few Layout events');
testRunner.log('Event sanity test done');
}
})
......@@ -2,7 +2,7 @@
Recording started
Tracing complete
Frames in TracingStartedInPage
url: inspector-protocol/timeline/page-frames.html name: parent: undefined nodeId: undefined
url: inspector-protocol/resources/inspector-protocol-page.html name: parent: undefined nodeId: undefined
url: data:text/html,<script>window.foo = 42</script> name: frame0 parent: string nodeId: number
Frames in CommitLoad events
url: about:blank name: Frame No. 1 parent: string nodeId: number
......
<html>
<head>
<script type="text/javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script>
<script type="text/javascript" src="../resources/tracing-test.js"></script>
<script>
function performActions()
{
var frame1 = document.createElement("iframe");
frame1.name = "Frame No. 1";
document.body.appendChild(frame1);
frame1.contentWindow.document.write("console.log('frame2')");
var frame2 = document.createElement("iframe");
frame2.src = "../resources/blank.html";
document.body.appendChild(frame2);
return new Promise(fulfill => { frame2.addEventListener("load", fulfill, false) });
}
function test()
{
InspectorTest.invokeAsyncWithTracing("performActions", finish);
function finish(devtoolsEvents, data)
{
InspectorTest.log("Frames in TracingStartedInPage");
var tracingStarted = InspectorTest.findEvent("TracingStartedInPage", "I");
for (var frame of tracingStarted.args["data"]["frames"] || [])
dumpFrame(frame);
InspectorTest.log("Frames in CommitLoad events");
var commitLoads = InspectorTest.findEvents("CommitLoad", "X");
for (var event of commitLoads)
dumpFrame(event.args["data"]);
InspectorTest.completeTest();
}
function dumpFrame(frame)
{
var url = frame.url.replace(/.*\/(([^/]*\/){2}[^/]*$)/, "$1");
InspectorTest.log(`url: ${url} name: ${frame.name} parent: ${typeof frame.parent} nodeId: ${typeof frame.nodeId}`);
}
}
</script>
</head>
<body onLoad="runTest();">
<iframe src="data:text/html,<script>window.foo = 42</script>" name="frame0"></iframe>
</body>
</html>
(async function(testRunner) {
let {page, session, dp} = await testRunner.startHTML(`
<iframe src='data:text/html,<script>window.foo = 42</script>' name='frame0'></iframe>
`, '');
function performActions() {
var frame1 = document.createElement('iframe');
frame1.name = 'Frame No. 1';
document.body.appendChild(frame1);
frame1.contentWindow.document.write('console.log("frame2")');
var frame2 = document.createElement('iframe');
frame2.src = 'blank.html';
document.body.appendChild(frame2);
return new Promise(fulfill => { frame2.addEventListener('load', fulfill, false) });
}
var TracingHelper = await testRunner.loadScript('../resources/tracing-test.js');
var tracingHelper = new TracingHelper(testRunner, session);
var data = await tracingHelper.invokeAsyncWithTracing(performActions);
testRunner.log('Frames in TracingStartedInPage');
var tracingStarted = tracingHelper.findEvent('TracingStartedInPage', 'I');
for (var frame of tracingStarted.args['data']['frames'] || [])
dumpFrame(frame);
testRunner.log('Frames in CommitLoad events');
var commitLoads = tracingHelper.findEvents('CommitLoad', 'X');
for (var event of commitLoads)
dumpFrame(event.args['data']);
testRunner.completeTest();
function dumpFrame(frame) {
var url = frame.url.replace(/.*\/(([^/]*\/){2}[^/]*$)/, '$1');
testRunner.log(`url: ${url} name: ${frame.name} parent: ${typeof frame.parent} nodeId: ${typeof frame.nodeId}`);
}
})
<html>
<head>
<script type="text/javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script>
<script type="text/javascript" src="../resources/tracing-test.js"></script>
<script>
function performAction()
{
var div = document.querySelector("#my-div");
div.addEventListener("click", function(e) { }, false);
div.click();
var iframe = document.createElement("iframe");
div.appendChild(iframe);
return new Promise(resolve => {
iframe.onload = resolve;
iframe.src = "../resources/blank.html";
});
}
function test()
{
InspectorTest.invokeAsyncWithTracing("performAction", finish);
function finish(devtoolsEvents)
{
function windowEventFilter(type, e)
{
return e.name === "EventDispatch" && e.args.data.type === type;
};
var windowEventNames = [ "click", "beforeunload", "unload", "load" ];
for (var i = 0; i < windowEventNames.length; i++) {
var eventName = windowEventNames[i];
var events = devtoolsEvents.filter(windowEventFilter.bind(this, eventName));
if (events.length >= 1) {
InspectorTest.log("SUCCESS: found " + eventName + " event");
} else {
fail(eventName + " event is missing", devtoolsEvents);
}
}
InspectorTest.completeTest();
}
function fail(message, devtoolsEvents)
{
var formattedEvents = devtoolsEvents.map(function(e)
{
return e.name + (e.args.data ? "(" + e.args.data.type + ")" : "");
});
InspectorTest.log("FAIL: " + message + " devtools.timeline events: " + JSON.stringify(formattedEvents, null, 2));
}
}
</script>
</head>
<body onLoad="runTest();">
<div id="my-div"></div>
</body>
</html>
(async function(testRunner) {
let {page, session, dp} = await testRunner.startHTML(`
<div id='my-div'></div>
`, '');
function performAction() {
var div = document.querySelector('#my-div');
div.addEventListener('click', function(e) { }, false);
div.click();
var iframe = document.createElement('iframe');
div.appendChild(iframe);
return new Promise(resolve => {
iframe.onload = resolve;
iframe.src = 'blank.html';
});
}
var TracingHelper = await testRunner.loadScript('../resources/tracing-test.js');
var tracingHelper = new TracingHelper(testRunner, session);
await tracingHelper.invokeAsyncWithTracing(performAction);
var windowEventNames = [ 'click', 'beforeunload', 'unload', 'load' ];
for (var eventName of windowEventNames) {
var events = tracingHelper.filterEvents(e => e.name === 'EventDispatch' && e.args.data.type === eventName);
if (events.length >= 1)
testRunner.log('SUCCESS: found ' + eventName + ' event');
else
testRunner.log('FAIL: ' + eventName + ' event is missing; devtools.timeline events: ' + tracingHelper.formattedEvents());
}
testRunner.completeTest();
})
DIV
Recording started
Tracing complete
UpdateLayoutTree frames match: true
......
<html>
<head>
<style>
.my-class {
min-width: 100px;
background-color: red;
}
</style>
<script type="text/javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script>
<script type="text/javascript" src="../resources/tracing-test.js"></script>
<script>
function performActions()
{
var div = document.querySelector("#myDiv");
div.classList.add("my-class");
div.offsetWidth;
return Promise.resolve();
}
function test()
{
InspectorTest.invokeAsyncWithTracing("performActions", finish);
function finish(devtoolsEvents)
{
var schedRecalc = InspectorTest.findEvent("ScheduleStyleRecalculation", "I");
var recalcBegin = InspectorTest.findEvent("UpdateLayoutTree", "B");
var recalcEnd = InspectorTest.findEvent("UpdateLayoutTree", "E");
InspectorTest.log("UpdateLayoutTree frames match: " + (schedRecalc.args.data.frame === recalcBegin.args.beginData.frame));
InspectorTest.log("UpdateLayoutTree elementCount > 0: " + (recalcEnd.args.elementCount > 0));
var invalidate = InspectorTest.findEvent("InvalidateLayout", "I");
var layoutBegin = InspectorTest.findEvent("Layout", "B");
var layoutEnd = InspectorTest.findEvent("Layout", "E");
InspectorTest.log("InvalidateLayout frames match: " + (recalcBegin.args.beginData.frame === invalidate.args.data.frame));
var beginData = layoutBegin.args.beginData;
InspectorTest.log("Layout frames match: " + (invalidate.args.data.frame === beginData.frame));
InspectorTest.log("dirtyObjects > 0: " + (beginData.dirtyObjects > 0));
InspectorTest.log("totalObjects > 0: " + (beginData.totalObjects > 0));
var endData = layoutEnd.args.endData;
InspectorTest.log("has rootNode id: " + (endData.rootNode > 0));
InspectorTest.log("has root quad: " + !!endData.root);
InspectorTest.log("SUCCESS: found all expected events.");
InspectorTest.completeTest();
}
}
</script>
</head>
<body onLoad="runTest();">
<div id="myDiv">DIV</div>
</body>
</html>
(async function(testRunner) {
let {page, session, dp} = await testRunner.startHTML(`
<style>
.my-class {
min-width: 100px;
background-color: red;
}
</style>
<div id='myDiv'>DIV</div>
`, '');
function performActions() {
var div = document.querySelector('#myDiv');
div.classList.add('my-class');
div.offsetWidth;
return Promise.resolve();
}
var TracingHelper = await testRunner.loadScript('../resources/tracing-test.js');
var tracingHelper = new TracingHelper(testRunner, session);
await tracingHelper.invokeAsyncWithTracing(performActions);
var schedRecalc = tracingHelper.findEvent('ScheduleStyleRecalculation', 'I');
var recalcBegin = tracingHelper.findEvent('UpdateLayoutTree', 'B');
var recalcEnd = tracingHelper.findEvent('UpdateLayoutTree', 'E');
testRunner.log('UpdateLayoutTree frames match: ' + (schedRecalc.args.data.frame === recalcBegin.args.beginData.frame));
testRunner.log('UpdateLayoutTree elementCount > 0: ' + (recalcEnd.args.elementCount > 0));
var invalidate = tracingHelper.findEvent('InvalidateLayout', 'I');
var layoutBegin = tracingHelper.findEvent('Layout', 'B');
var layoutEnd = tracingHelper.findEvent('Layout', 'E');
testRunner.log('InvalidateLayout frames match: ' + (recalcBegin.args.beginData.frame === invalidate.args.data.frame));
var beginData = layoutBegin.args.beginData;
testRunner.log('Layout frames match: ' + (invalidate.args.data.frame === beginData.frame));
testRunner.log('dirtyObjects > 0: ' + (beginData.dirtyObjects > 0));
testRunner.log('totalObjects > 0: ' + (beginData.totalObjects > 0));
var endData = layoutEnd.args.endData;
testRunner.log('has rootNode id: ' + (endData.rootNode > 0));
testRunner.log('has root quad: ' + !!endData.root);
testRunner.log('SUCCESS: found all expected events.');
testRunner.completeTest();
})
DIV
Recording started
Tracing complete
RequestAnimationFrame has frame: true
......
<html>
<head>
<script type="text/javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script>
<script type="text/javascript" src="../resources/tracing-test.js"></script>
<script>
function performActions()
{
var callback;
var promise = new Promise((fulfill) => callback = fulfill);
var rafId2;
var rafId1 = requestAnimationFrame(() => callback({ rafId1: rafId1, rafId2: rafId2 }));
rafId2 = requestAnimationFrame(function() { });
cancelAnimationFrame(rafId2);
return promise;
}
function test()
{
InspectorTest.invokeAsyncWithTracing("performActions", finish);
function finish(devtoolsEvents, data)
{
var firedRaf = data.rafId1;
var canceledRaf = data.rafId2;
function hasRafId(id, e) { return e.args.data.id === id}
var raf1 = InspectorTest.findEvent("RequestAnimationFrame", "I", hasRafId.bind(this, firedRaf));
var raf2 = InspectorTest.findEvent("RequestAnimationFrame", "I", hasRafId.bind(this, canceledRaf));
InspectorTest.log("RequestAnimationFrame has frame: " + !!raf1.args.data.frame);
InspectorTest.log("RequestAnimationFrame frames match: " + (raf1.args.data.frame === raf2.args.data.frame));
InspectorTest.findEvent("CancelAnimationFrame", "I", hasRafId.bind(this, canceledRaf));
InspectorTest.findEvent("FireAnimationFrame", "X", hasRafId.bind(this, firedRaf));
InspectorTest.log("SUCCESS: found all expected events.");
InspectorTest.completeTest();
}
}
</script>
</head>
<body onLoad="runTest();">
<div id="myDiv">DIV</div>
</body>
</html>
(async function(testRunner) {
let {page, session, dp} = await testRunner.startHTML(`
<div id='myDiv'>DIV</div>
`, '');
function performActions() {
var callback;
var promise = new Promise((fulfill) => callback = fulfill);
var rafId2;
var rafId1 = requestAnimationFrame(() => callback({ rafId1: rafId1, rafId2: rafId2 }));
rafId2 = requestAnimationFrame(function() { });
cancelAnimationFrame(rafId2);
return promise;
}
function hasRafId(id, e) {
return e.args.data.id === id;
}
var TracingHelper = await testRunner.loadScript('../resources/tracing-test.js');
var tracingHelper = new TracingHelper(testRunner, session);
var data = await tracingHelper.invokeAsyncWithTracing(performActions);
var firedRaf = data.rafId1;
var canceledRaf = data.rafId2;
var raf1 = tracingHelper.findEvent('RequestAnimationFrame', 'I', hasRafId.bind(null, firedRaf));
var raf2 = tracingHelper.findEvent('RequestAnimationFrame', 'I', hasRafId.bind(null, canceledRaf));
testRunner.log('RequestAnimationFrame has frame: ' + !!raf1.args.data.frame);
testRunner.log('RequestAnimationFrame frames match: ' + (raf1.args.data.frame === raf2.args.data.frame));
tracingHelper.findEvent('CancelAnimationFrame', 'I', hasRafId.bind(null, canceledRaf));
tracingHelper.findEvent('FireAnimationFrame', 'X', hasRafId.bind(null, firedRaf));
testRunner.log('SUCCESS: found all expected events.');
testRunner.completeTest();
})
DIV
Recording started
SUCCESS: testFunctionTimerFired
Tracing complete
TimerInstall has frame: true
TimerInstall frames match: true
......
<html>
<head>
<script type="text/javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script>
<script type="text/javascript" src="../resources/tracing-test.js"></script>
<script>
function performActions()
{
var callback;
var promise = new Promise((fulfill) => callback = fulfill);
var timerId = setTimeout(function()
{
evaluateInFrontend("InspectorTest.testFunctionTimerFired(" + timerId + ", " + timerId2 + ")");
callback();
}, 0);
var timerId2 = setTimeout(function() { }, 0);
clearTimeout(timerId2);
return promise;
}
function test()
{
InspectorTest.invokeAsyncWithTracing("performActions", finish);
var firedTimerId;
var removedTimerId;
InspectorTest.testFunctionTimerFired = function(timerId1, timerId2)
{
firedTimerId = timerId1;
removedTimerId = timerId2;
InspectorTest.log("SUCCESS: testFunctionTimerFired");
}
function finish(devtoolsEvents)
{
function hasTimerId(id, e) { return e.args.data.timerId === id}
var installTimer1 = InspectorTest.findEvent("TimerInstall", "I", hasTimerId.bind(this, firedTimerId));
var installTimer2 = InspectorTest.findEvent("TimerInstall", "I", hasTimerId.bind(this, removedTimerId));
InspectorTest.log("TimerInstall has frame: " + !!installTimer1.args.data.frame);
InspectorTest.log("TimerInstall frames match: " + (installTimer1.args.data.frame === installTimer2.args.data.frame));
InspectorTest.findEvent("TimerRemove", "I", hasTimerId.bind(this, removedTimerId));
InspectorTest.findEvent("TimerFire", "X", hasTimerId.bind(this, firedTimerId));
InspectorTest.log("SUCCESS: found all expected events.");
InspectorTest.completeTest();
}
}
</script>
</head>
<body onLoad="runTest();">
<div id="myDiv">DIV</div>
</body>
</html>
(async function(testRunner) {
let {page, session, dp} = await testRunner.startHTML(`
<div id='myDiv'>DIV</div>
`, '');
function performActions() {
var callback;
var promise = new Promise((fulfill) => callback = fulfill);
var timerId = setTimeout(function() {
callback({timerId: timerId, timerId2: timerId2});
}, 0);
var timerId2 = setTimeout(function() { }, 0);
clearTimeout(timerId2);
return promise;
}
function hasTimerId(id, e) {
return e.args.data.timerId === id;
}
var TracingHelper = await testRunner.loadScript('../resources/tracing-test.js');
var tracingHelper = new TracingHelper(testRunner, session);
var data = await tracingHelper.invokeAsyncWithTracing(performActions);
var firedTimerId = data.timerId;
var removedTimerId = data.timerId2;
var installTimer1 = tracingHelper.findEvent('TimerInstall', 'I', hasTimerId.bind(this, firedTimerId));
var installTimer2 = tracingHelper.findEvent('TimerInstall', 'I', hasTimerId.bind(this, removedTimerId));
testRunner.log('TimerInstall has frame: ' + !!installTimer1.args.data.frame);
testRunner.log('TimerInstall frames match: ' + (installTimer1.args.data.frame === installTimer2.args.data.frame));
tracingHelper.findEvent('TimerRemove', 'I', hasTimerId.bind(this, removedTimerId));
tracingHelper.findEvent('TimerFire', 'X', hasTimerId.bind(this, firedTimerId));
testRunner.log('SUCCESS: found all expected events.');
testRunner.completeTest();
})
CONSOLE ERROR: line 3: Uncaught Error
Tests that console message from worker contains stack trace.
Worker created
Worker created
......
<html>
<head>
<script type="text/javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script>
<script>
var worker1;
var worker2;
function startWorkers()
{
worker1 = new Worker("resources/worker-with-throw.js");
worker1.onerror = function(e) {
e.preventDefault();
worker1.terminate();
}
worker2 = new Worker("resources/worker-with-throw.js");
}
function test()
{
InspectorTest.sendCommandOrDie("Target.setAutoAttach", {autoAttach: true, waitForDebuggerOnStart: false}, didEnableWorkerDebugging);
function didEnableWorkerDebugging(event)
{
InspectorTest.sendCommandOrDie("Runtime.evaluate", { expression: "startWorkers()" });
}
var workerRequestId = 1;
function sendCommandToWorker(method, params, workerId)
{
InspectorTest.sendCommand("Target.sendMessageToTarget",
{
"targetId": workerId,
"message": JSON.stringify({ "method": method,
"params": params,
"id": workerRequestId++ })
});
}
var waitForWorkers = 2;
InspectorTest.eventHandler["Target.attachedToTarget"] = function(messageObject)
{
var workerId = messageObject["params"]["targetInfo"]["targetId"];
InspectorTest.log("Worker created");
sendCommandToWorker("Runtime.enable", {}, workerId);
if (!--waitForWorkers)
InspectorTest.sendCommandOrDie("Runtime.evaluate", { expression: "worker1.postMessage(239);worker2.postMessage(42);" });
}
var workerTerminated = false;
var messageReceived = false;
InspectorTest.eventHandler["Target.receivedMessageFromTarget"] = function(messageObject)
{
var message = JSON.parse(messageObject["params"]["message"]);
if (message["method"] === "Runtime.exceptionThrown") {
var callFrames = message.params.exceptionDetails.stackTrace ? message.params.exceptionDetails.stackTrace.callFrames : [];
InspectorTest.log(callFrames.length > 0 ? "Message with stack trace received." : "[FAIL] Message contains empty stack trace");
messageReceived = true;
if (messageReceived && workerTerminated)
InspectorTest.completeTest();
}
}
InspectorTest.eventHandler["Target.detachedFromTarget"] = function(messageObject)
{
InspectorTest.eventHandler["Target.detachedFromTarget"] = undefined;
workerTerminated = true;
if (messageReceived && workerTerminated)
InspectorTest.completeTest();
}
}
</script>
</head>
<body onload="runTest()">Tests that console message from worker contains stack trace.</body>
</html>
(async function(testRunner) {
let {page, session, dp} = await testRunner.startBlank('Tests that console message from worker contains stack trace.');
var workerRequestId = 1;
function sendCommandToWorker(method, params, workerId) {
dp.Target.sendMessageToTarget({
targetId: workerId,
message: JSON.stringify({ method: method, params: params, id: workerRequestId++ })
});
}
var waitForWorkers = 2;
dp.Target.onAttachedToTarget(messageObject => {
var workerId = messageObject['params']['targetInfo']['targetId'];
testRunner.log('Worker created');
sendCommandToWorker('Runtime.enable', {}, workerId);
if (!--waitForWorkers)
session.evaluate('worker1.postMessage(239);worker2.postMessage(42);');
});
var workerTerminated = false;
var messageReceived = false;
dp.Target.onReceivedMessageFromTarget(messageObject => {
var message = JSON.parse(messageObject['params']['message']);
if (message['method'] === 'Runtime.exceptionThrown') {
var callFrames = message.params.exceptionDetails.stackTrace ? message.params.exceptionDetails.stackTrace.callFrames : [];
testRunner.log(callFrames.length > 0 ? 'Message with stack trace received.' : '[FAIL] Message contains empty stack trace');
messageReceived = true;
if (messageReceived && workerTerminated)
testRunner.completeTest();
}
});
function onDetached(messageObject) {
dp.Target.offDetachedFromTarget(onDetached);
workerTerminated = true;
if (messageReceived && workerTerminated)
testRunner.completeTest();
}
dp.Target.onDetachedFromTarget(onDetached);
await dp.Target.setAutoAttach({autoAttach: true, waitForDebuggerOnStart: false});
session.evaluate(`
window.worker1 = new Worker('${testRunner.url('../resources/worker-with-throw.js')}');
window.worker1.onerror = function(e) {
e.preventDefault();
worker1.terminate();
}
window.worker2 = new Worker('${testRunner.url('../resources/worker-with-throw.js')}');
`);
})
CONSOLE MESSAGE: line 6: message0
CONSOLE MESSAGE: line 6: message1
CONSOLE MESSAGE: line 6: message2
CONSOLE ERROR: line 4: Uncaught (in promise) throw1
CONSOLE MESSAGE: line 6: message3
CONSOLE MESSAGE: line 6: message4
CONSOLE MESSAGE: line 6: message5
CONSOLE MESSAGE: line 6: message6
Starting worker
Logging in worker: message0
Got log message from page: message0
......
<html>
<head>
<script type="text/javascript" src="../../http/tests/inspector-protocol/resources/inspector-protocol-test.js"></script>
<script>
var worker;
var onMessageCallbacks = {};
function startWorker()
{
var callback;
var promise = new Promise((fulfill) => callback = fulfill);
worker = new Worker("../resources/worker-console-worker.js");
worker.onmessage = function(event) {
worker.onmessage = onMessageFromWorker;
callback();
};
return promise;
}
function logInWorkerFromPage(message, callback)
{
onMessageCallbacks[message] = callback;
worker.postMessage(message);
}
function onMessageFromWorker(event)
{
var callback = onMessageCallbacks[event.data];
delete onMessageCallbacks[event.data];
if (callback)
callback();
}
function stopWorker()
{
worker.terminate();
worker = null;
}
function test()
{
var workerEventHandler = {};
InspectorTest.eventHandler["Target.attachedToTarget"] = onWorkerCreated;
InspectorTest.eventHandler["Target.receivedMessageFromTarget"] = onWorkerMessage;
workerEventHandler["Runtime.consoleAPICalled"] = onConsoleAPICalledFromWorker;
var workerId;
function onWorkerCreated(payload)
{
InspectorTest.log("Worker.created");
workerId = payload.params.targetInfo.targetId;
}
var requestId = 0;
var dispatchTable = [];
function sendCommandToWorker(method, params, callback)
{
dispatchTable[++requestId] = callback;
var messageObject = {
"method": method,
"params": params,
"id": requestId
};
InspectorTest.sendCommandOrDie("Target.sendMessageToTarget", {
targetId: workerId,
message: JSON.stringify(messageObject)
});
}
function onWorkerMessage(payload)
{
if (payload.params.targetId !== workerId)
InspectorTest.log("targetId mismatch");
var messageObject = JSON.parse(payload.params.message);
var messageId = messageObject["id"];
if (typeof messageId === "number") {
var handler = dispatchTable[messageId];
dispatchTable[messageId] = null;
if (handler && typeof handler === "function")
handler(messageObject);
} else {
var eventName = messageObject["method"];
var eventHandler = workerEventHandler[eventName];
if (eventHandler)
eventHandler(messageObject);
}
}
function logInWorker(message, next)
{
InspectorTest.log("Logging in worker: " + message);
InspectorTest.eventHandler["Log.entryAdded"] = onLogEntry;
InspectorTest.evaluateInPage("logInWorkerFromPage(\"" + message + "\")");
function onLogEntry(payload)
{
InspectorTest.log("Got log message from page: " + payload.params.entry.text);
delete InspectorTest.eventHandler["Log.entryAdded"];
next();
}
}
var gotMessages = [];
var waitingForMessage;
var waitingForMessageCallback;
function onConsoleAPICalledFromWorker(payload)
{
var message = payload.params.args[0].value;
InspectorTest.log("Got console API call from worker: " + message);
gotMessages.push(message);
if (message === waitingForMessage)
waitingForMessageCallback();
}
function waitForMessage(message, next)
{
if (gotMessages.indexOf(message) !== -1) {
next();
return;
}
waitingForMessage = message;
waitingForMessageCallback = next;
}
var steps = [
function listenToConsole(next)
{
InspectorTest.sendCommandOrDie("Log.enable", {}, next);
},
function start0(next)
{
InspectorTest.log("Starting worker");
InspectorTest.evaluateInPageAsync("startWorker()").then(next);
},
function log0(next)
{
logInWorker("message0", next);
},
function stop0(next)
{
InspectorTest.log("Stopping worker");
InspectorTest.evaluateInPage("stopWorker()", next);
},
function start1(next)
{
InspectorTest.log("Starting worker");
InspectorTest.evaluateInPageAsync("startWorker()").then(next);
},
function log1(next)
{
logInWorker("message1", next);
},
function enable1(next)
{
InspectorTest.log("Starting autoattach");
InspectorTest.sendCommandOrDie("Target.setAutoAttach", {autoAttach: true, waitForDebuggerOnStart: false}, next);
},
function consoleEnable1(next)
{
InspectorTest.log("Sending Runtime.enable to worker");
waitForMessage("message1", next);
sendCommandToWorker("Runtime.enable", {});
},
function log2(next)
{
logInWorker("message2", next);
},
function waitForMessage2(next)
{
waitForMessage("message2", next);
},
function throw1(next)
{
logInWorker("throw1", next);
},
function disable1(next)
{
InspectorTest.log("Stopping autoattach");
InspectorTest.sendCommandOrDie("Target.setAutoAttach", {autoAttach: false, waitForDebuggerOnStart: false}, next);
},
function log3(next)
{
logInWorker("message3", next);
},
function stop1(next)
{
InspectorTest.log("Stopping worker");
InspectorTest.evaluateInPage("stopWorker()", next);
},
function enable2(next)
{
InspectorTest.log("Starting autoattach");
InspectorTest.sendCommandOrDie("Target.setAutoAttach", {autoAttach: true, waitForDebuggerOnStart: false}, next);
},
function start2(next)
{
InspectorTest.log("Starting worker");
InspectorTest.evaluateInPageAsync("startWorker()").then(next);
},
function log4(next)
{
logInWorker("message4", next);
},
function consoleEnable2(next)
{
InspectorTest.log("Sending Runtime.enable to worker");
waitForMessage("message4", next);
sendCommandToWorker("Runtime.enable", {});
},
function log5(next)
{
logInWorker("message5", next);
},
function waitForMessage5(next)
{
waitForMessage("message5", next);
},
function stop2(next)
{
InspectorTest.log("Stopping worker");
InspectorTest.evaluateInPage("stopWorker()", next);
},
function start3(next)
{
InspectorTest.log("Starting worker");
InspectorTest.evaluateInPageAsync("startWorker()").then(next);
},
function log6(next)
{
logInWorker("message6", next);
},
function stop3(next)
{
InspectorTest.log("Stopping worker");
InspectorTest.evaluateInPage("stopWorker()", next);
},
function disable2(next)
{
InspectorTest.log("Stopping autoattach");
InspectorTest.sendCommandOrDie("Target.setAutoAttach", {autoAttach: false, waitForDebuggerOnStart: false}, next);
}
];
function runNextStep()
{
if (!steps.length) {
InspectorTest.completeTest();
return;
}
var nextStep = steps.shift();
InspectorTest.safeWrap(nextStep)(runNextStep);
}
runNextStep();
}
</script>
</head>
<body onload="runTest()">
</body>
</html>
(async function(testRunner) {
let {page, session, dp} = await testRunner.startBlank('');
await session.evaluate(`
var worker = null;
var onMessageCallbacks = {};
function startWorker() {
var callback;
var promise = new Promise((fulfill) => callback = fulfill);
worker = new Worker('${testRunner.url('../resources/worker-console-worker.js')}');
worker.onmessage = function(event) {
worker.onmessage = onMessageFromWorker;
callback();
};
return promise;
}
function logInWorkerFromPage(message, callback) {
onMessageCallbacks[message] = callback;
worker.postMessage(message);
}
function onMessageFromWorker(event) {
var callback = onMessageCallbacks[event.data];
delete onMessageCallbacks[event.data];
if (callback)
callback();
}
function stopWorker() {
worker.terminate();
worker = null;
}
`);
var workerEventHandler = {};
dp.Target.onAttachedToTarget(onWorkerCreated);
dp.Target.onReceivedMessageFromTarget(onWorkerMessage);
workerEventHandler['Runtime.consoleAPICalled'] = onConsoleAPICalledFromWorker;
var workerId;
function onWorkerCreated(payload) {
testRunner.log('Worker.created');
workerId = payload.params.targetInfo.targetId;
}
var requestId = 0;
var dispatchTable = [];
function sendCommandToWorker(method, params, callback) {
dispatchTable[++requestId] = callback;
var messageObject = {
'method': method,
'params': params,
'id': requestId
};
dp.Target.sendMessageToTarget({
targetId: workerId,
message: JSON.stringify(messageObject)
});
}
function onWorkerMessage(payload) {
if (payload.params.targetId !== workerId)
testRunner.log('targetId mismatch');
var messageObject = JSON.parse(payload.params.message);
var messageId = messageObject['id'];
if (typeof messageId === 'number') {
var handler = dispatchTable[messageId];
dispatchTable[messageId] = null;
if (handler && typeof handler === 'function')
handler(messageObject);
} else {
var eventName = messageObject['method'];
var eventHandler = workerEventHandler[eventName];
if (eventHandler)
eventHandler(messageObject);
}
}
function logInWorker(message, next) {
testRunner.log('Logging in worker: ' + message);
dp.Log.onEntryAdded(onLogEntry);
session.evaluate('logInWorkerFromPage(\'' + message + '\')');
function onLogEntry(payload) {
testRunner.log('Got log message from page: ' + payload.params.entry.text);
dp.Log.offEntryAdded(onLogEntry);
next();
}
}
var gotMessages = [];
var waitingForMessage;
var waitingForMessageCallback;
function onConsoleAPICalledFromWorker(payload) {
var message = payload.params.args[0].value;
testRunner.log('Got console API call from worker: ' + message);
gotMessages.push(message);
if (message === waitingForMessage)
waitingForMessageCallback();
}
function waitForMessage(message, next) {
if (gotMessages.indexOf(message) !== -1) {
next();
return;
}
waitingForMessage = message;
waitingForMessageCallback = next;
}
var steps = [
function listenToConsole(next) {
dp.Log.enable().then(next);
},
function start0(next) {
testRunner.log('Starting worker');
session.evaluateAsync('startWorker()').then(next);
},
function log0(next) {
logInWorker('message0', next);
},
function stop0(next) {
testRunner.log('Stopping worker');
session.evaluate('stopWorker()').then(next);
},
function start1(next) {
testRunner.log('Starting worker');
session.evaluateAsync('startWorker()').then(next);
},
function log1(next) {
logInWorker('message1', next);
},
function enable1(next) {
testRunner.log('Starting autoattach');
dp.Target.setAutoAttach({autoAttach: true, waitForDebuggerOnStart: false}).then(next);
},
function consoleEnable1(next) {
testRunner.log('Sending Runtime.enable to worker');
waitForMessage('message1', next);
sendCommandToWorker('Runtime.enable', {});
},
function log2(next) {
logInWorker('message2', next);
},
function waitForMessage2(next) {
waitForMessage('message2', next);
},
function throw1(next) {
logInWorker('throw1', next);
},
function disable1(next) {
testRunner.log('Stopping autoattach');
dp.Target.setAutoAttach({autoAttach: false, waitForDebuggerOnStart: false}).then(next);
},
function log3(next) {
logInWorker('message3', next);
},
function stop1(next) {
testRunner.log('Stopping worker');
session.evaluate('stopWorker()').then(next);
},
function enable2(next) {
testRunner.log('Starting autoattach');
dp.Target.setAutoAttach({autoAttach: true, waitForDebuggerOnStart: false}).then(next);
},
function start2(next) {
testRunner.log('Starting worker');
session.evaluateAsync('startWorker()').then(next);
},
function log4(next) {
logInWorker('message4', next);
},
function consoleEnable2(next) {
testRunner.log('Sending Runtime.enable to worker');
waitForMessage('message4', next);
sendCommandToWorker('Runtime.enable', {});
},
function log5(next) {
logInWorker('message5', next);
},
function waitForMessage5(next) {
waitForMessage('message5', next);
},
function stop2(next) {
testRunner.log('Stopping worker');
session.evaluate('stopWorker()').then(next);
},
function start3(next) {
testRunner.log('Starting worker');
session.evaluateAsync('startWorker()').then(next);
},
function log6(next) {
logInWorker('message6', next);
},
function stop3(next) {
testRunner.log('Stopping worker');
session.evaluate('stopWorker()').then(next);
},
function disable2(next) {
testRunner.log('Stopping autoattach');
dp.Target.setAutoAttach({autoAttach: false, waitForDebuggerOnStart: false}).then(next);
}
];
function runNextStep() {
if (!steps.length) {
testRunner.completeTest();
return;
}
var nextStep = steps.shift();
nextStep(runNextStep);
}
runNextStep();
})
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