Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

/* Any copyright is dedicated to the Public Domain.
"use strict";
const EXAMPLE_COM_URI =
const EXAMPLE_NET_URI =
const ORG_URL_ROOT = URL_ROOT.replace("example.com", "example.org");
const TEST_ORG_URI =
ORG_URL_ROOT + "doc_inspector_fission_frame_navigation.html";
add_task(async function () {
const { inspector } = await openInspectorForURL(TEST_ORG_URI);
const tree = `
id="root"
iframe
#document
html
head
body
id="org"`;
// Note: the assertMarkupViewAsTree uses very high level APIs and is similar
// to what should happen when a user interacts with the markup view.
// It is important to avoid explicitly fetching walkers or node fronts during
// the test, as it might cause reparenting of remote frames and make the test
// succeed without actually testing that the feature works correctly.
await assertMarkupViewAsTree(tree, "#root", inspector);
await navigateIframeTo(inspector, EXAMPLE_COM_URI);
const treeAfterLoadingCom = `
id="root"
iframe
#document
html
head
body
id="com"`;
await assertMarkupViewAsTree(treeAfterLoadingCom, "#root", inspector);
await navigateIframeTo(inspector, EXAMPLE_NET_URI);
const treeAfterLoadingNet = `
id="root"
iframe
#document
html
head
body
id="net"`;
await assertMarkupViewAsTree(treeAfterLoadingNet, "#root", inspector);
});
/**
* This test will check the behavior when navigating a frame which is not
* visible in the markup view, because its parentNode has not been expanded yet.
*
* We expect a root-node resource to be emitted, but ideally we should not
* initialize the walker and inspector actors for the target of this root-node
* resource.
*/
add_task(async function navigateFrameNotExpandedInMarkupView() {
if (!isFissionEnabled()) {
// This test only makes sense with Fission and remote frames, otherwise the
// root-node resource will not be emitted for a frame navigation.
return;
}
const { inspector } = await openInspectorForURL(TEST_ORG_URI);
const resourceCommand = inspector.toolbox.resourceCommand;
// At this stage the expected layout of the markup view is
// v html (expanded)
// v body (expanded)
// > p (collapsed)
// > div (collapsed)
//
// The iframe we are about to navigate is therefore hidden and we are not
// watching it - ie, it is not in the list of known NodeFronts/Actors.
const resource = await navigateIframeTo(inspector, EXAMPLE_COM_URI);
is(
resource.resourceType,
resourceCommand.TYPES.ROOT_NODE,
"A resource with resourceType ROOT_NODE was received when navigating"
);
// This highlights what doesn't work with the current approach.
// Since the root-node resource is a NodeFront watched via the WalkerFront,
// watching it for a new remote frame target implies initializing the
// inspector & walker fronts.
//
// If the resource was not a front (eg ContentDOMreference?) and was emitted
// by the target actor instead of the walker actor, the client can decide if
// the inspector and walker fronts should be initialized or not.
//
// In this test scenario, the children of the iframe were not known by the
// inspector before this navigation. Per the explanation above, the new target
// should not have an already instantiated inspector front.
//
// This should be fixed when implementing the RootNode resource on the server
todo(
!resource.targetFront.getCachedFront("inspector"),
"The inspector front for the new target should not be initialized"
);
});
async function navigateIframeTo(inspector, url) {
info("Navigate the test iframe to " + url);
const { commands } = inspector;
const { resourceCommand } = inspector.toolbox;
const onTargetProcessed = waitForTargetProcessed(commands, url);
const { onResource: onNewRoot } = await resourceCommand.waitForNextResource(
resourceCommand.TYPES.ROOT_NODE,
{
ignoreExistingResources: true,
}
);
info("Update the src attribute of the iframe tag");
await SpecialPowers.spawn(gBrowser.selectedBrowser, [url], function (_url) {
content.document.querySelector("iframe").setAttribute("src", _url);
});
info("Wait for frameLoad/newRoot to resolve");
const newRootResult = await onNewRoot;
info("Wait for pending children updates");
await inspector.markup._waitForChildren();
if (isFissionEnabled()) {
info("Wait until the new target has been processed by TargetCommand");
await onTargetProcessed;
}
// Note: the newRootResult changes when the test runs with or without fission.
return newRootResult;
}
/**
* Returns a promise that waits until the provided commands's TargetCommand has fully
* processed a target with the provided URL.
* This will avoid navigating again before the new resource command have fully
* attached to the new target.
*/
function waitForTargetProcessed(commands, url) {
return new Promise(resolve => {
const onTargetProcessed = targetFront => {
if (targetFront.url !== encodeURI(url)) {
return;
}
commands.targetCommand.off(
"processed-available-target",
onTargetProcessed
);
resolve();
};
commands.targetCommand.on("processed-available-target", onTargetProcessed);
});
}