| <!DOCTYPE html> |
| <html> |
| <head> |
| <script src="../../http/tests/inspector/resources/inspector-test.js"></script> |
| <script>function inlineScriptOne() { return 1; }</script> |
| <script> |
| function inlineScriptTwo() { |
| return 2; |
| } |
| //# sourceURL=inline-script-two.js |
| </script> |
| <script> |
| function triggerResourceWithNormalScript() { |
| loadNormalScript(); |
| } |
| |
| function loadNormalScript() { |
| return new Promise((resolve, reject) => { |
| let script = document.createElement("script"); |
| script.src = "resources/relationship-normal.js"; |
| script.addEventListener("load", resolve, {once: true}); |
| script.addEventListener("error", reject, {once: true}); |
| document.body.appendChild(script); |
| }); |
| } |
| |
| async function triggerRepeatedResourcesWithNormalScripts() { |
| await loadNormalScript(); |
| await loadNormalScript(); |
| } |
| |
| function triggerResourceWithNamedScript() { |
| let script = document.createElement("script"); |
| script.src = "resources/relationship-named.js"; |
| document.body.appendChild(script); |
| } |
| |
| function triggerScriptWithoutResource() { |
| eval("//# sourceURL=script-only.js\n1+1"); |
| } |
| |
| function triggerScriptElement() { |
| let script = document.createElement("script"); |
| script.text = "//# sourceURL=dynamically-added-script-element.js\n1+1"; |
| document.body.appendChild(script); |
| } |
| |
| function test() |
| { |
| let suite = InspectorTest.createAsyncSuite("WI.Script and WI.Resource relationship"); |
| |
| function validateNormalRelationship(resource, script) { |
| InspectorTest.expectThat(resource.url === script.url, "Resource and Script have the same URL."); |
| InspectorTest.expectThat(resource.scripts.length === 1, "Resource should be related to one script."); |
| InspectorTest.expectThat(resource.scripts[0] === script, "Resource should be related to the newly added script."); |
| InspectorTest.expectThat(script.resource === resource, "Script should be related to the resource."); |
| } |
| |
| suite.addTestCase({ |
| name: "ScriptWithResource", |
| description: "Normal relationship between a script and a resource.", |
| test(resolve, reject) { |
| let script = null; |
| let resource = null; |
| |
| WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.ScriptAdded, scriptListener); |
| WI.Frame.awaitEvent(WI.Frame.Event.ResourceWasAdded) |
| .then((event) => { |
| resource = event.data.resource; |
| validateRelationship(); |
| }); |
| |
| function scriptListener(event) { |
| if (!event.data.script.url) |
| return; |
| |
| InspectorTest.expectThat(!script, "Only one Script should be added."); |
| |
| script = event.data.script; |
| validateRelationship(); |
| } |
| |
| function validateRelationship() { |
| if (!resource || !script) |
| return; |
| |
| validateNormalRelationship(resource, script); |
| InspectorTest.expectThat(!script.sourceURL, "Script should not have a sourceURL."); |
| |
| WI.debuggerManager.removeEventListener(WI.DebuggerManager.Event.ScriptAdded, scriptListener, null); |
| resolve(); |
| } |
| |
| InspectorTest.evaluateInPage("triggerResourceWithNormalScript()"); |
| } |
| }); |
| |
| suite.addTestCase({ |
| name: "NamedScriptWithResource", |
| description: "Normal relationship between a named script and a resource.", |
| test(resolve, reject) { |
| let script = null; |
| let resource = null; |
| |
| WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.ScriptAdded, scriptListener); |
| WI.Frame.awaitEvent(WI.Frame.Event.ResourceWasAdded) |
| .then((event) => { |
| resource = event.data.resource; |
| validateRelationship(); |
| }); |
| |
| function scriptListener(event) { |
| if (!event.data.script.url) |
| return; |
| |
| InspectorTest.expectThat(!script, "Only one Script should be added."); |
| |
| script = event.data.script; |
| validateRelationship(); |
| } |
| |
| function validateRelationship() { |
| if (!resource || !script) |
| return; |
| |
| validateNormalRelationship(resource, script); |
| InspectorTest.expectThat(script.sourceURL === "foo.js", "Script should have a sourceURL."); |
| WI.debuggerManager.removeEventListener(WI.DebuggerManager.Event.ScriptAdded, scriptListener, null); |
| resolve(); |
| } |
| |
| InspectorTest.evaluateInPage("triggerResourceWithNamedScript()"); |
| } |
| }); |
| |
| suite.addTestCase({ |
| name: "RepeatedScriptsWithResources", |
| description: "Repeated loads of the same JavaScript URL should each associate with the only unassociated Resource.", |
| async test() { |
| await NetworkAgent.setResourceCachingDisabled(true); |
| |
| let scripts = []; |
| let resourceChangedPromises = []; |
| |
| let scriptsAddedPromise = new Promise((resolve) => { |
| function handleScriptAdded(event) { |
| let script = event.data.script; |
| if (!script.url?.endsWith("/relationship-normal.js")) |
| return; |
| |
| scripts.push(script); |
| if (!script.resource) |
| resourceChangedPromises.push(script.awaitEvent(WI.Script.Event.ResourceChanged)); |
| if (scripts.length !== 2) |
| return; |
| |
| WI.debuggerManager.removeEventListener(WI.DebuggerManager.Event.ScriptAdded, handleScriptAdded); |
| resolve(); |
| } |
| WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.ScriptAdded, handleScriptAdded); |
| }); |
| |
| InspectorTest.evaluateInPage("triggerRepeatedResourcesWithNormalScripts()"); |
| await scriptsAddedPromise; |
| await Promise.all(resourceChangedPromises); |
| |
| let resources = scripts.map((script) => script.resource); |
| InspectorTest.expectEqual(scripts.length, 2, "Should add two JavaScript scripts."); |
| InspectorTest.expectTrue(resources.every((resource) => resource instanceof WI.Resource), "Each JavaScript script should associate with a Resource."); |
| InspectorTest.expectEqual(new Set(resources).size, 2, "Each JavaScript script should associate with a distinct Resource."); |
| InspectorTest.expectTrue(resources.every((resource, index) => resource.scripts.includes(scripts[index])), "Each Resource should associate with its JavaScript script."); |
| |
| await NetworkAgent.setResourceCachingDisabled(false); |
| } |
| }); |
| |
| suite.addTestCase({ |
| name: "ScriptWithoutResource", |
| description: "A named eval does not have a resource.", |
| test(resolve, reject) { |
| WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.ScriptAdded, scriptListener); |
| let resourceListener = WI.Frame.singleFireEventListener(WI.Frame.Event.ResourceWasAdded, (event) => { |
| InspectorTest.fail("Resource should not be added."); |
| reject(); |
| }); |
| |
| function scriptListener(event) { |
| if (!event.data.script.sourceURL) |
| return; |
| |
| InspectorTest.pass("Script was added."); |
| let script = event.data.script; |
| |
| InspectorTest.expectThat(script.resource === null, "Script should not be associated with a Resource."); |
| InspectorTest.expectThat(script.sourceURL === "script-only.js", "Script should have a sourceURL."); |
| |
| WI.Frame.removeEventListener(WI.Frame.Event.ResourceWasAdded, resourceListener, null); |
| WI.debuggerManager.removeEventListener(WI.DebuggerManager.Event.ScriptAdded, scriptListener, null); |
| resolve(); |
| } |
| |
| InspectorTest.evaluateInPage("triggerScriptWithoutResource()"); |
| } |
| }); |
| |
| suite.addTestCase({ |
| name: "DynamicallyAddedScriptElementNoResource", |
| description: "A dynamically added script element has no resource.", |
| test(resolve, reject) { |
| WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.ScriptAdded, scriptListener); |
| |
| function scriptListener(event) { |
| if (event.data.script.sourceURL !== "dynamically-added-script-element.js") |
| return; |
| InspectorTest.pass("Script was added."); |
| let script = event.data.script; |
| |
| InspectorTest.expectThat(script.dynamicallyAddedScriptElement, "Script should identify as a dynamically added script element."); |
| InspectorTest.expectThat(script.resource === null, "Script should not be associated when a resource."); |
| |
| WI.debuggerManager.removeEventListener(WI.DebuggerManager.Event.ScriptAdded, scriptListener, null); |
| resolve(); |
| } |
| |
| InspectorTest.evaluateInPage("triggerScriptElement()"); |
| } |
| }); |
| |
| suite.addTestCase({ |
| name: "DocumentWithInlineScripts", |
| description: "A document resource may be associated with multiple inline scripts.", |
| async test() { |
| let mainResource = WI.networkManager.mainFrame.mainResource; |
| while (mainResource.scripts.length < 4) |
| await mainResource.awaitEvent(WI.Resource.Event.ScriptAssociated); |
| |
| let scripts = mainResource.scripts.slice().sort((a, b) => a.range.startLine - b.range.startLine); |
| |
| // Scripts are: |
| // 1. <script> with inlineScriptOne() |
| // 2. <script> with inlineScriptTwo() |
| // 3. This <script> with test() |
| // 4. The <body onload> inline script event listener |
| |
| InspectorTest.expectThat(scripts.length === 4, "Main Resource should have 4 scripts."); |
| InspectorTest.expectThat(!scripts[0].sourceURL, "Inline script 1 does not have a sourceURL."); |
| InspectorTest.expectThat(scripts[1].sourceURL === "inline-script-two.js", "Inline script 2 has a sourceURL."); |
| InspectorTest.expectThat(!scripts[2].sourceURL, "Inline script 3 does not have a sourceURL."); |
| InspectorTest.expectThat(!scripts[3].sourceURL, "Inline script 4 does not have a sourceURL."); |
| |
| InspectorTest.expectThat(scripts[0].range.startLine < 15, "Inline script 1 should have a low start line."); |
| InspectorTest.expectThat(scripts[1].range.startLine < 15, "Inline script 2 should have a low start line."); |
| InspectorTest.expectThat(scripts[2].range.startLine < 15, "Inline script 3 should have a low start line."); |
| InspectorTest.expectThat(scripts[3].range.startLine > 100, "Inline script 4 should have a high start line."); |
| } |
| }); |
| |
| suite.runTestCasesAndFinish(); |
| } |
| </script> |
| </head> |
| <body onload="runTest()"> |
| <p>WI.Script and WI.Resource relationship.</p> |
| </body> |
| </html> |