Source code
Revision control
Copy as Markdown
Other Tools
Test Info: Warnings
-
CI results over the last 21 days
- This test is know to fail with pattern: a11y_checks
- Manifest: devtools/client/application/test/browser/browser.toml
/* Any copyright is dedicated to the Public Domain.
"use strict";
const HTTPS_ROOT = URL_ROOT.replace("http:", "https:");
const SOURCE_URL = HTTPS_ROOT + "resources/service-workers/empty.html";
const STATUS_TARGET =
HTTPS_ROOT + "resources/speculative-loads/prefetch-status.sjs";
const RUN = Date.now();
add_setup(async function () {
await enableApplicationPanel();
await SpecialPowers.pushPrefEnv({
set: [
["devtools.application.speculativeLoads", true],
["dom.speculation_rules.enabled", true],
["dom.performance.deliverytype.enabled", false],
],
});
});
async function waitForStatus(panel, status) {
const doc = panel.panelWin.document;
await waitFor(
() =>
doc.querySelector(".speculative-loads-status")?.dataset.prefetchStatus ===
status
);
const node = doc.querySelector(".speculative-loads-status");
is(
doc.querySelector(".speculative-loads-pane .app-page__title").textContent,
"Speculative load status for this page",
"The existing section heading is preserved"
);
const expectedText = {
prefetched: "Navigation used a prefetched document response",
"not-prefetched": "Navigation did not use a prefetched document response",
unknown: "Prefetch reuse status unavailable",
};
is(
node.textContent,
expectedText[status],
"The status text matches the browser signal"
);
}
async function prefetchTarget(browser, url) {
const completed = TestUtils.topicObserved("http-on-stop-request", subject => {
return subject.QueryInterface(Ci.nsIHttpChannel).URI.spec === url;
});
await SpecialPowers.spawn(browser, [url], target => {
const rule = content.document.createElement("script");
rule.type = "speculationrules";
rule.textContent = JSON.stringify({
prefetch: [{ source: "list", eagerness: "immediate", urls: [target] }],
});
content.document.head.appendChild(rule);
});
await completed;
}
async function assertChannelStatus(browser, expected) {
const activated = await SpecialPowers.spawn(browser, [], () => {
return docShell.currentDocumentChannel.loadInfo
.activatedFromNavigationalPrefetch;
});
is(
activated,
expected,
"The document channel has the expected activation flag"
);
}
add_task(async function test_prefetch_activation_and_history() {
let { panel, tab, toolbox } = await openNewTabAndApplicationPanel(SOURCE_URL);
await selectPage(panel, "speculative-loads");
await waitForStatus(panel, "not-prefetched");
const target = `${STATUS_TARGET}?activation=${RUN}`;
await prefetchTarget(tab.linkedBrowser, target);
await waitForStatus(panel, "not-prefetched");
await navigateTo(target);
await assertChannelStatus(tab.linkedBrowser, true);
await waitForStatus(panel, "prefetched");
const deliveryType = await SpecialPowers.spawn(tab.linkedBrowser, [], () => {
return (
content.performance.getEntriesByType("navigation")[0].deliveryType ?? ""
);
});
is(
deliveryType,
"",
"The panel works without the web-exposed deliveryType signal"
);
info(
"Opening DevTools after activation reads the existing document's status"
);
await toolbox.closeToolbox();
toolbox = await gDevTools.showToolboxForTab(tab, { toolId: "application" });
panel = toolbox.getCurrentPanel();
await selectPage(panel, "speculative-loads");
await waitForStatus(panel, "prefetched");
const otherOrigin = SOURCE_URL.replace("example.com", "example.org");
await SpecialPowers.spawn(tab.linkedBrowser, [otherOrigin], async url => {
const iframe = content.document.createElement("iframe");
const loaded = new Promise(resolve => {
iframe.onload = resolve;
});
iframe.src = url;
content.document.body.appendChild(iframe);
await loaded;
});
await waitForStatus(panel, "prefetched");
info("A normal navigation clears the previous document's positive status");
await navigateTo(otherOrigin);
await assertChannelStatus(tab.linkedBrowser, false);
await waitForStatus(panel, "not-prefetched");
info("Restoring the prefetched document restores its status");
const backShown = BrowserTestUtils.waitForContentEvent(
tab.linkedBrowser,
"pageshow"
);
const switched = toolbox.commands.targetCommand.once("switched-target");
gBrowser.goBack();
await backShown;
await switched;
await assertChannelStatus(tab.linkedBrowser, true);
await waitForStatus(panel, "prefetched");
info("Reloading creates a normal navigation");
await navigateTo(target);
await assertChannelStatus(tab.linkedBrowser, false);
await waitForStatus(panel, "not-prefetched");
await BrowserTestUtils.removeTab(tab);
});
add_task(async function test_cache_hit_is_not_prefetch_activation() {
const { panel, tab } = await openNewTabAndApplicationPanel(SOURCE_URL);
await selectPage(panel, "speculative-loads");
const target = `${STATUS_TARGET}?ordinary-cache=${RUN}`;
await SpecialPowers.spawn(tab.linkedBrowser, [target], async url => {
const response = await content.fetch(url);
await response.text();
});
await navigateTo(target);
await assertChannelStatus(tab.linkedBrowser, false);
await waitForStatus(panel, "not-prefetched");
await BrowserTestUtils.removeTab(tab);
});
add_task(async function test_no_store_prefetch_activation() {
const { panel, tab } = await openNewTabAndApplicationPanel(SOURCE_URL);
await selectPage(panel, "speculative-loads");
const target = `${STATUS_TARGET}?no-store=${RUN}`;
await prefetchTarget(tab.linkedBrowser, target);
await navigateTo(target);
await assertChannelStatus(tab.linkedBrowser, true);
await waitForStatus(panel, "prefetched");
await BrowserTestUtils.removeTab(tab);
});
add_task(async function test_failed_prefetch_is_not_activation() {
const { panel, tab } = await openNewTabAndApplicationPanel(SOURCE_URL);
await selectPage(panel, "speculative-loads");
const target = `${STATUS_TARGET}?failure=${RUN}`;
await prefetchTarget(tab.linkedBrowser, target);
await navigateTo(target);
await assertChannelStatus(tab.linkedBrowser, false);
await waitForStatus(panel, "not-prefetched");
await BrowserTestUtils.removeTab(tab);
});