blob: 2701b22abe5213a9f180c1df7b78e41354dfd6b1 [file] [log] [blame]
<!DOCTYPE html>
<html>
<head>
<script src="../../http/tests/inspector/resources/protocol-test.js"></script>
<script>
let worker1 = new Worker("resources/worker-1.js");
let worker2 = new Worker("resources/worker-2.js");
let worker3 = null;
function createWorker3() {
worker3 = new Worker("resources/worker-3.js");
}
function terminateWorker2FromPage() {
worker2.terminate();
}
function terminateWorker3FromWorker() {
worker3.postMessage("close");
}
function terminateWorker1ViaCollection() {
worker1 = null;
}
function test()
{
let workers = [];
function addWorker(workerId, url) {
workers.push({workerId, url});
workers.sort((a, b) => a.url.localeCompare(b.url));
}
function removeWorker(workerId) {
workers = workers.filter((x) => x.workerId !== workerId);
}
function dumpWorkers() {
for (let {workerId, url} of workers)
ProtocolTest.log("Worker - " + sanitizeURL(url));
if (!workers.length)
ProtocolTest.log("No Workers");
}
async function checkInternalProperties(expression, {terminated} = {}) {
let evaluateResult = await InspectorProtocol.awaitCommand({
method: "Runtime.evaluate",
params: {
expression,
objectGroup: "test",
},
});
ProtocolTest.assert(evaluateResult.result.type === "object", `Evaluate result of '${expression}' should have type 'object'.`);
ProtocolTest.assert(evaluateResult.result.className === "Worker", `Evaluate result of '${expression}' should have className 'Worker'.`);
let getPropertiesResult = await InspectorProtocol.awaitCommand({
method: "Runtime.getProperties",
params: {
objectId: evaluateResult.result.objectId,
},
});
let internalProperties = getPropertiesResult.internalProperties;
ProtocolTest.assert(internalProperties.length === 1, `Worker '${expression}' should only have one internal property.`);
ProtocolTest.assert(internalProperties[0].name === "terminated", `Worker '${expression}' should have 'terminated' internal property.`);
ProtocolTest.assert(internalProperties[0].value.type === "boolean", `Internal 'terminated' property of '${expression}' should be a boolean.`);
ProtocolTest.assert(internalProperties[0].value.value === terminated, `Internal 'terminated' property of '${expression}' should have value '${terminated}'.`);
}
let triggerNextCreate;
let triggerNextTerminate;
function waitForWorkerCreatedEvent(callback) {
return new Promise((resolve, reject) => {
triggerNextCreate = resolve;
});
}
function waitForWorkerTerminatedEvent(callback) {
return new Promise((resolve, reject) => {
triggerNextTerminate = resolve;
});
}
InspectorProtocol.eventHandler["Worker.workerCreated"] = (messageObject) => {
addWorker(messageObject.params.workerId, messageObject.params.url);
InspectorProtocol.sendCommand("Worker.initialized", {workerId: messageObject.params.workerId});
if (triggerNextCreate)
triggerNextCreate();
};
InspectorProtocol.eventHandler["Worker.workerTerminated"] = (messageObject) => {
removeWorker(messageObject.params.workerId);
if (triggerNextTerminate)
triggerNextTerminate();
};
let suite = ProtocolTest.createAsyncSuite("Worker.CreateAndTerminate");
suite.addTestCase({
name: "Worker.enable",
description: "Worker.enable informs the frontend of the two existing Workers",
async test() {
await InspectorProtocol.awaitCommand({method: "Worker.enable", params: {}});
ProtocolTest.expectEqual(workers.length, 2, "Should be informed of two existing Workers.");
dumpWorkers();
await Promise.all([
checkInternalProperties(`worker1`, {terminated: false}),
checkInternalProperties(`worker2`, {terminated: false}),
]);
}
});
suite.addTestCase({
name: "Worker.workerCreated",
description: "Should receive a Worker.workerCreated event when creating a Worker.",
async test() {
await Promise.all([
waitForWorkerCreatedEvent(),
ProtocolTest.evaluateInPage("createWorker3()"),
]);
ProtocolTest.pass("Worker.workerCreated");
dumpWorkers();
await Promise.all([
checkInternalProperties(`worker1`, {terminated: false}),
checkInternalProperties(`worker2`, {terminated: false}),
checkInternalProperties(`worker3`, {terminated: false}),
]);
}
});
suite.addTestCase({
name: "Worker.workerTerminated.Page",
description: "Should receive a Worker.workerTerminated event when terminating a Worker from the Page.",
async test() {
await Promise.all([
waitForWorkerTerminatedEvent(),
ProtocolTest.evaluateInPage("terminateWorker2FromPage()"),
]);
ProtocolTest.pass("Worker.workerTerminated");
dumpWorkers();
await Promise.all([
checkInternalProperties(`worker1`, {terminated: false}),
checkInternalProperties(`worker2`, {terminated: true}),
checkInternalProperties(`worker3`, {terminated: false}),
]);
}
});
suite.addTestCase({
name: "Worker.workerTerminated.Worker",
description: "Should receive a Worker.workerTerminated event when terminating a Worker from the Worker.",
async test() {
await Promise.all([
waitForWorkerTerminatedEvent(),
ProtocolTest.evaluateInPage("terminateWorker3FromWorker()"),
]);
ProtocolTest.pass("Worker.workerTerminated");
dumpWorkers();
await Promise.all([
checkInternalProperties(`worker1`, {terminated: false}),
checkInternalProperties(`worker2`, {terminated: true}),
]);
}
});
suite.addTestCase({
name: "Worker.workerTerminated.GC",
description: "Should receive a Worker.workerTerminated event when terminating a Worker via Garbage Collection.",
async test() {
let workerTerminatedPromise = waitForWorkerTerminatedEvent();
await ProtocolTest.evaluateInPage("terminateWorker1ViaCollection()");
await InspectorProtocol.awaitCommand({method: "Runtime.releaseObjectGroup", params: {objectGroup: "test"}});
await InspectorProtocol.awaitCommand({method: "Heap.gc", params: {}});
await workerTerminatedPromise;
ProtocolTest.pass("Worker.workerTerminated");
dumpWorkers();
await checkInternalProperties(`worker2`, {terminated: true});
}
});
suite.runTestCasesAndFinish();
}
</script>
</head>
<body onload="runTest()">
<p>Tests for Worker.workerCreated and Worker.workerTerminated events.</p>
</body>
</html>