blob: 511d8065a6e3f0f5b44ed9cf226d4f5af7f4610a [file] [edit]
<!DOCTYPE html>
<html>
<head>
<script src="../../http/tests/inspector/resources/inspector-test.js"></script>
<script src="../../resources/wasm-builder.js"></script>
<script src="../debugger/wasm/resources/test-modules.js"></script>
<script>
function triggerAddScriptElement() {
let script = document.createElement("script");
script.text = "console.log('dynamically added script element');";
document.body.appendChild(script);
}
function loadScriptInFrame(frameName)
{
let script = frames[frameName].document.createElement("script");
script.src = new URL("../../resources/wasm-builder.js?frame=" + frameName, location.href).href;
frames[frameName].document.head.appendChild(script);
}
function triggerAddScriptElementInFrame(frameName)
{
let script = frames[frameName].document.createElement("script");
script.text = "window.dynamicScriptWasAdded = Boolean(true);";
frames[frameName].document.body.appendChild(script);
}
let wasmInstances = [];
function instantiateWasmInFrame(frameName, moduleName)
{
let targetWindow = frameName === undefined ? window : frames[frameName];
let module = new targetWindow.WebAssembly.Module(createNamedAddWasmBytes(moduleName));
wasmInstances.push(new targetWindow.WebAssembly.Instance(module));
}
function test()
{
let suite = InspectorTest.createAsyncSuite("WI.Frame.extraScriptCollection");
let mainFrame = WI.networkManager.mainFrame;
async function targetForFrame(frame)
{
if (!WI.isSiteIsolationEnabled())
return WI.mainTarget;
let match = frame.id.match(/^frame-(\d+)\.(\d+)$/);
console.assert(match);
let targetIdentifier = `frame-${match[2]}-${match[1]}`;
while (true) {
let target = WI.targetManager.targetForIdentifier(targetIdentifier);
if (target)
return target;
await WI.targetManager.awaitEvent(WI.TargetManager.Event.TargetAdded);
}
}
function scriptsForAllTargets()
{
let scripts = [];
for (let target of WI.targets) {
if (target.hasDomain("Debugger"))
scripts.pushAll(WI.debuggerManager.dataForTarget(target).scripts);
}
return scripts;
}
async function evaluateAndAwaitScript(frame, expression, predicate)
{
let knownScripts = new Set(scriptsForAllTargets());
await InspectorTest.evaluateInPage(expression);
let targetData = WI.debuggerManager.dataForTarget(await targetForFrame(frame));
while (true) {
let script = targetData.scripts.find((script) => predicate(script) && !knownScripts.has(script));
if (script)
return script;
await WI.debuggerManager.awaitEvent(WI.DebuggerManager.Event.ScriptAdded);
}
}
function evaluateAndAwaitWebAssemblyScript(frame, expression)
{
return evaluateAndAwaitScript(frame, expression, (script) => script.sourceType === WI.Script.SourceType.WebAssembly);
}
suite.addTestCase({
name: "FrameHasNoExtraScriptsYet",
description: "No extra scripts yet.",
test(resolve, reject) {
InspectorTest.expectEqual(mainFrame.extraScriptCollection.size, 0, "Main frame should have no dynamic scripts.");
resolve();
}
});
suite.addTestCase({
name: "HiddenConsoleEvaluationIsNotExtraScript",
description: "A hidden console evaluation should not be added to the frame's extra script collection.",
async test() {
InspectorTest.expectFalse(WI.settings.debugShowConsoleEvaluations.value, "Console evaluations should be hidden by default.");
let initialExtraScriptCount = mainFrame.extraScriptCollection.size;
await new Promise((resolve) => {
WI.runtimeManager.evaluateInInspectedWindow("1 + 1", {objectGroup: "test"}, resolve);
});
InspectorTest.expectEqual(mainFrame.extraScriptCollection.size, initialExtraScriptCount, "The hidden console evaluation should not add an extra script.");
}
});
suite.addTestCase({
name: "AddExtraScript",
description: "Add extra script.",
test(resolve, reject) {
WI.networkManager.mainFrame.awaitEvent(WI.Frame.Event.ExtraScriptAdded)
.then((event) => {
InspectorTest.pass("ExtraScriptAdded event fired.");
InspectorTest.expectThat(event.data.script.dynamicallyAddedScriptElement, "Script should identify as dynamic.");
InspectorTest.expectEqual(mainFrame.extraScriptCollection.size, 1, "Main frame should have 1 dynamic script.");
})
.then(resolve, reject);
InspectorTest.evaluateInPage("triggerAddScriptElement()");
}
});
suite.addTestCase({
name: "AssociateDynamicJavaScriptWithChildFrame",
description: "A dynamic JavaScript script should belong to the exact child frame for its execution context.",
async test() {
let childFrames = Array.from(mainFrame.childFrameCollection);
let firstChildFrame = childFrames.find((frame) => frame.name === "first");
let secondChildFrame = childFrames.find((frame) => frame.name === "second");
InspectorTest.assert(firstChildFrame, "Should find the first child frame.");
InspectorTest.assert(secondChildFrame, "Should find the second child frame.");
InspectorTest.expectEqual(firstChildFrame.url, secondChildFrame.url, "The child frames should have the same URL.");
let script = await evaluateAndAwaitScript(secondChildFrame, "triggerAddScriptElementInFrame('second')", (script) => script.dynamicallyAddedScriptElement);
InspectorTest.expectEqual(script.parentFrame, secondChildFrame, "The dynamic JavaScript script should belong to the second child frame.");
InspectorTest.expectFalse(firstChildFrame.extraScriptCollection.has(script), "The first child frame should not contain the second child frame's dynamic JavaScript script.");
InspectorTest.expectTrue(secondChildFrame.extraScriptCollection.has(script), "The second child frame should contain its dynamic JavaScript script.");
}
});
suite.addTestCase({
name: "AssociateJavaScriptWithChildFrame",
description: "A JavaScript script should belong to the child frame for its execution context.",
async test() {
let firstChildFrame = Array.from(mainFrame.childFrameCollection).find((frame) => frame.name === "first");
InspectorTest.assert(firstChildFrame, "Should find the first child frame.");
let script = await evaluateAndAwaitScript(firstChildFrame, "loadScriptInFrame('first')", (script) => script.url.includes("wasm-builder.js?frame=first"));
InspectorTest.expectNotNull(script.resource, "The JavaScript script should be associated with a Resource.");
InspectorTest.expectEqual(script.parentFrame, firstChildFrame, "The JavaScript script should belong to the first child frame.");
InspectorTest.expectFalse(firstChildFrame.extraScriptCollection.has(script), "The resource-backed JavaScript script should not be an extra script.");
}
});
suite.addTestCase({
name: "AddWebAssemblyScriptToMainFrame",
description: "A WebAssembly script should belong to the main frame that created it.",
async test() {
let script = await evaluateAndAwaitWebAssemblyScript(mainFrame, "instantiateWasmInFrame(undefined, 'main-frame-math.wasm')");
InspectorTest.expectNull(script.resource, "The WebAssembly script should not be associated with a Resource.");
InspectorTest.expectEqual(script.parentFrame, mainFrame, "The WebAssembly script should belong to the main frame.");
InspectorTest.expectTrue(mainFrame.extraScriptCollection.has(script), "The main frame should contain the WebAssembly script.");
InspectorTest.expectEqual(script.displayName, "main-frame-math.wasm", "The WebAssembly script should use its module name for display.");
}
});
suite.addTestCase({
name: "AddWebAssemblyScriptToChildFrame",
description: "A WebAssembly script should belong to the exact child frame that created it.",
async test() {
let childFrames = Array.from(mainFrame.childFrameCollection);
let firstChildFrame = childFrames.find((frame) => frame.name === "first");
let secondChildFrame = childFrames.find((frame) => frame.name === "second");
InspectorTest.assert(firstChildFrame, "Should find the first child frame.");
InspectorTest.assert(secondChildFrame, "Should find the second child frame.");
InspectorTest.expectEqual(firstChildFrame.url, secondChildFrame.url, "The child frames should have the same URL.");
let firstScript = await evaluateAndAwaitWebAssemblyScript(firstChildFrame, "instantiateWasmInFrame('first', 'shared-frame-math.wasm')");
InspectorTest.expectEqual(firstScript.parentFrame, firstChildFrame, "The first WebAssembly script should belong to the first child frame.");
InspectorTest.expectFalse(mainFrame.extraScriptCollection.has(firstScript), "The main frame should not contain the first child frame's WebAssembly script.");
InspectorTest.expectTrue(firstChildFrame.extraScriptCollection.has(firstScript), "The first child frame should contain its WebAssembly script.");
InspectorTest.expectFalse(secondChildFrame.extraScriptCollection.has(firstScript), "The second child frame should not contain the first child frame's WebAssembly script.");
InspectorTest.expectEqual(firstScript.displayName, "shared-frame-math.wasm", "The first WebAssembly script should use its module name for display.");
let secondScript = await evaluateAndAwaitWebAssemblyScript(secondChildFrame, "instantiateWasmInFrame('second', 'shared-frame-math.wasm')");
InspectorTest.expectEqual(secondScript.parentFrame, secondChildFrame, "The second WebAssembly script should belong to the second child frame.");
InspectorTest.expectFalse(mainFrame.extraScriptCollection.has(secondScript), "The main frame should not contain the second child frame's WebAssembly script.");
InspectorTest.expectFalse(firstChildFrame.extraScriptCollection.has(secondScript), "The first child frame should not contain the second child frame's WebAssembly script.");
InspectorTest.expectTrue(secondChildFrame.extraScriptCollection.has(secondScript), "The second child frame should contain its WebAssembly script.");
InspectorTest.expectEqual(secondScript.displayName, "shared-frame-math.wasm", "The second WebAssembly script should use its module name for display.");
InspectorTest.expectNotEqual(firstScript.url, secondScript.url, "Equal module names should not replace the scripts' unique URLs.");
}
});
suite.runTestCasesAndFinish();
}
</script>
</head>
<body onload="runTest()">
<p>WI.Frame.extraScriptCollection.</p>
<iframe name="first" src="../page/resources/blank.html"></iframe>
<iframe name="second" src="../page/resources/blank.html"></iframe>
</body>
</html>