Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

/* Any copyright is dedicated to the Public Domain.
"use strict";
// Fix blank inspector bug when opening DevTools on a webpage with a document
// where document.write is called without ever calling document.close.
// Such a document remains forever in the "loading" readyState. See Bug 1765760.
const TEST_URL =
`data:text/html;charset=utf-8,` +
encodeURIComponent(`
<!DOCTYPE html>
<html lang="en">
<body>
<div id=outsideframe></div>
<script type="text/javascript">
const iframe = document.createElement("iframe");
iframe.src = "about:blank";
iframe.addEventListener('load', () => {
iframe.contentDocument.write('<div id=inframe>inframe</div>');
}, true);
document.body.appendChild(iframe);
</script>
</body>
</html>
`);
add_task(async function testSlowLoadingFrame() {
const loadingTab = BrowserTestUtils.addTab(gBrowser, TEST_URL);
gBrowser.selectedTab = loadingTab;
// Note: we cannot use `await addTab` here because the iframe never finishes
// loading. But we still want to wait for the frame to reach the loading state
// and to display a test element so that we can reproduce the initial issue
// fixed by Bug 1765760.
info("Wait for the loading iframe to be ready to test");
await TestUtils.waitForCondition(async () => {
try {
return await ContentTask.spawn(gBrowser.selectedBrowser, {}, () => {
const iframe = content.document.querySelector("iframe");
return (
iframe?.contentDocument.readyState === "loading" &&
iframe.contentDocument.getElementById("inframe")
);
});
} catch (e) {
return false;
}
});
const { inspector } = await openInspector();
info("Check the markup view displays the loading iframe successfully");
await assertMarkupViewAsTree(
`
body
div id="outsideframe"
script!ignore-children
iframe
#document
html
head
body
div id="inframe"`,
"body",
inspector
);
});
add_task(async function testSlowLoadingDocument() {
info("Create a test server serving a slow document");
const httpServer = createTestHTTPServer();
httpServer.registerContentType("html", "text/html");
// This promise allows to block serving the complete document from the test.
let unblockRequest;
const onRequestUnblocked = new Promise(r => (unblockRequest = r));
httpServer.registerPathHandler(`/`, async function (request, response) {
response.processAsync();
response.setStatusLine(request.httpVersion, 200, "OK");
// Split the page content in 2 parts:
// - opening body tag and the "#start" div will be returned immediately
// - "#end" div and closing body tag are blocked on a promise.
const page_start = "<body><div id='start'>start</div>";
const page_end = "<div id='end'>end</div></body>";
const page = page_start + page_end;
response.setHeader("Content-Type", "text/html; charset=utf-8", false);
response.setHeader("Content-Length", page.length + "", false);
response.write(page_start);
await onRequestUnblocked;
response.write(page_end);
response.finish();
});
const port = httpServer.identity.primaryPort;
const TEST_URL_2 = `http://localhost:${port}/`;
// Same as in the other task, we cannot wait for the full load.
info("Open a new tab on TEST_URL_2 and select it");
const loadingTab = BrowserTestUtils.addTab(gBrowser, TEST_URL_2);
gBrowser.selectedTab = loadingTab;
info("Wait for the #start div to be available in the document");
await TestUtils.waitForCondition(async () => {
try {
return await ContentTask.spawn(gBrowser.selectedBrowser, {}, () =>
content.document.getElementById("start")
);
} catch (e) {
return false;
}
});
const { inspector } = await openInspector();
info("Check that the inspector is not blank and only shows the #start div");
await assertMarkupViewAsTree(
`
body
div id="start"`,
"body",
inspector
);
// Navigate to about:blank to clean the state.
await navigateTo("about:blank");
const markuploaded = inspector.once("markuploaded");
const onNewRoot = inspector.once("new-root");
const onUpdated = inspector.once("inspector-updated");
await navigateTo(TEST_URL_2, { waitForLoad: false });
info("Wait for the #start div to be available as a markupview container");
await TestUtils.waitForCondition(async () => {
const nodeFront = await getNodeFront("#start", inspector);
return nodeFront && getContainerForNodeFront(nodeFront, inspector);
});
info("Check that the inspector is not blank and only shows the #start div");
await assertMarkupViewAsTree(
`
body
div id="start"`,
"body",
inspector
);
info("Unblock the document request");
unblockRequest();
info("Wait for the #end div to be available as a markupview container");
await TestUtils.waitForCondition(async () => {
const nodeFront = await getNodeFront("#end", inspector);
return nodeFront && getContainerForNodeFront(nodeFront, inspector);
});
info("Check that the inspector will ultimately show the #end div");
await assertMarkupViewAsTree(
`
body
div id="start"
div id="end"`,
"body",
inspector
);
info(
"Waiting for inspector to update after having released the document load"
);
await markuploaded;
await onNewRoot;
await onUpdated;
});