зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
f3df9272e0
Коммит
299f9180e4
|
@ -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,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче