Bug 1628473 - Add test for remote frame navigation r=rcaliman,nchevobbe

Depends on D79674

Differential Revision: https://phabricator.services.mozilla.com/D79675
This commit is contained in:
Julian Descottes 2020-07-16 16:22:02 +00:00
Родитель f3df9272e0
Коммит 299f9180e4
4 изменённых файлов: 190 добавлений и 0 удалений

Просмотреть файл

@ -11,6 +11,7 @@ support-files =
doc_inspector_delete-selected-node-02.html
doc_inspector_embed.html
doc_inspector_eyedropper_disabled.xhtml
doc_inspector_fission_frame_navigation.html
doc_inspector_highlight_after_transition.html
doc_inspector_highlighter-comments.html
doc_inspector_highlighter-geometry_01.html
@ -73,6 +74,7 @@ skip-if = (os == 'win' && processor == 'aarch64') # bug 1533490
[browser_inspector_destroy-after-navigation.js]
[browser_inspector_destroy-before-ready.js]
[browser_inspector_expand-collapse.js]
[browser_inspector_fission_frame_navigation.js]
[browser_inspector_fission_switch_target.js]
[browser_inspector_highlighter-01.js]
[browser_inspector_highlighter-02.js]

Просмотреть файл

@ -0,0 +1,149 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const EXAMPLE_COM_URI =
"http://example.com/document-builder.sjs?html=<div id=com>com";
const EXAMPLE_NET_URI =
"http://example.net/document-builder.sjs?html=<div id=net>net";
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() {
await pushPref("devtools.contenttoolbox.fission", true);
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;
}
await pushPref("devtools.contenttoolbox.fission", true);
const { inspector } = await openInspectorForURL(TEST_ORG_URI);
const resourceWatcher = inspector.toolbox.resourceWatcher;
// 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, targetFront } = await navigateIframeTo(
inspector,
EXAMPLE_COM_URI
);
is(
resource?.resourceType,
resourceWatcher.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
// in https://bugzilla.mozilla.org/show_bug.cgi?id=1644190
todo(
!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 resourceWatcher = inspector.toolbox.resourceWatcher;
let onNewRoot;
if (isFissionEnabled()) {
// With Fission, the frame navigation will result in a new root-node
// resource.
onNewRoot = waitForResourceOnce(
resourceWatcher,
resourceWatcher.TYPES.ROOT_NODE
);
} else {
// Without Fission, the frame navigation is handled on the server and will
// create two (fake) mutations: frameLoad + childList.
onNewRoot = Promise.all([
waitForMutation(inspector, "childList"),
waitForMutation(inspector, "frameLoad"),
]);
}
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();
// Note: the newRootResult changes when the test runs with or without fission.
return newRootResult;
}

Просмотреть файл

@ -0,0 +1,15 @@
<!-- Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ -->
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Test remote frame navigation</title>
</head>
<body>
<p>Test remote frame navigation</p>
<div id="root">
<iframe src='http://example.org/document-builder.sjs?html=<div id=org>org'></iframe>
</div>
</body>
</html>

Просмотреть файл

@ -1080,3 +1080,27 @@ async function moveWindowTo(win, left, top) {
function getCurrentTestFilePath() {
return gTestPath.replace("chrome://mochitests/content/browser/", "");
}
/**
* Wait for a single resource of the provided resourceType.
*
* @param {ResourceWatcher} resourceWatcher
* The ResourceWatcher instance that should emit the expected resource.
* @param {String} resourceType
* One of ResourceWatcher.TYPES, type of the expected resource.
* @return {Object}
* - resource {Object} the resource itself
* - targetFront {TargetFront} the target which owns the resource
*/
function waitForResourceOnce(resourceWatcher, resourceType) {
return new Promise(resolve => {
const onAvailable = ({ targetFront, resource }) => {
resolve({ targetFront, resource });
resourceWatcher.unwatchResources([resourceType], { onAvailable });
};
resourceWatcher.watchResources([resourceType], {
ignoreExistingResources: true,
onAvailable,
});
});
}