Bug 1703275 - [devtools] Share implementation for inspector test helpers selectNodeInFrames & getNodeFrontInFrame r=nchevobbe

Depends on D110746

Differential Revision: https://phabricator.services.mozilla.com/D110943
This commit is contained in:
Julian Descottes 2021-04-07 06:42:56 +00:00
Родитель 73ec85076f
Коммит 72743c63e7
21 изменённых файлов: 96 добавлений и 170 удалений

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

@ -29,8 +29,9 @@ add_task(async function() {
});
await ToolboxTask.importFunctions({
getNodeFront,
getNodeFrontInFrames,
selectNode,
// selectNodeInFrames depends on selectNode and getNodeFront.
// selectNodeInFrames depends on selectNode, getNodeFront, getNodeFrontInFrames.
selectNodeInFrames,
});

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

@ -29,8 +29,9 @@ add_task(async function() {
});
await ToolboxTask.importFunctions({
getNodeFront,
getNodeFrontInFrames,
selectNode,
// selectNodeInFrames depends on selectNode and getNodeFront.
// selectNodeInFrames depends on selectNode, getNodeFront, getNodeFrontInFrames.
selectNodeInFrames,
});

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

@ -63,8 +63,9 @@ add_task(async function() {
});
await ToolboxTask.importFunctions({
getNodeFront,
getNodeFrontInFrames,
selectNode,
// selectNodeInFrames depends on selectNode and getNodeFront.
// selectNodeInFrames depends on selectNode, getNodeFront, getNodeFrontInFrames.
selectNodeInFrames,
});

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

@ -39,8 +39,9 @@ add_task(async function() {
});
await ToolboxTask.importFunctions({
getNodeFront,
getNodeFrontInFrames,
selectNode,
// selectNodeInFrames depends on selectNode and getNodeFront.
// selectNodeInFrames depends on selectNode, getNodeFront, getNodeFrontInFrames.
selectNodeInFrames,
});

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

@ -28,9 +28,10 @@ add_task(async function() {
});
await ToolboxTask.importFunctions({
getNodeFront,
getNodeFrontInFrames,
getRuleViewLinkByIndex,
selectNode,
// selectNodeInFrames depends on selectNode and getNodeFront.
// selectNodeInFrames depends on selectNode, getNodeFront, getNodeFrontInFrames.
selectNodeInFrames,
});

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

@ -18,7 +18,7 @@ async function testResizingInIframe(inspector, boxmodel, testActor) {
info("Test that resizing an element in an iframe updates its box model");
info("Selecting the nested test node");
await selectNodeInIframe2("div", inspector);
await selectNodeInFrames(["iframe", "iframe", "div"], inspector);
info("Checking that the box model view shows the right value");
const sizeElt = boxmodel.document.querySelector(".boxmodel-size > span");
@ -46,7 +46,7 @@ async function testReflowsAfterIframeDeletion(inspector, boxmodel, testActor) {
await onInspectorUpdated;
info("Selecting the test node in iframe1");
await selectNodeInIframe1("p", inspector);
await selectNodeInFrames(["iframe", "p"], inspector);
info("Checking that the box model view shows the right value");
const sizeElt = boxmodel.document.querySelector(".boxmodel-size > span");
@ -62,19 +62,6 @@ async function testReflowsAfterIframeDeletion(inspector, boxmodel, testActor) {
is(sizeElt.textContent, "200\u00D7100");
}
async function selectNodeInIframe1(selector, inspector) {
const iframe1 = await getNodeFront("iframe", inspector);
const node = await getNodeFrontInFrame(selector, iframe1, inspector);
await selectNode(node, inspector);
}
async function selectNodeInIframe2(selector, inspector) {
const iframe1 = await getNodeFront("iframe", inspector);
const iframe2 = await getNodeFrontInFrame("iframe", iframe1, inspector);
const node = await getNodeFrontInFrame(selector, iframe2, inspector);
await selectNode(node, inspector);
}
async function setStyleInIframe1(testActor, selector, propertyName, value) {
await testActor.eval(`
content.document.querySelector("iframe")

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

@ -30,8 +30,7 @@ add_task(async function() {
in: 0.521,
};
const node = await getNodeFrontInFrame(selector, "#frame", inspector);
await selectNode(node, inspector);
await selectNodeInFrames(["#frame", selector], inspector);
info("Check that font editor shows font-size value in original units");
const fontSize = getPropertyValue(viewDoc, property);

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

@ -19,8 +19,7 @@ add_task(async function() {
const { inspector, toolbox } = await openInspectorForURL(encodeURI(TEST_URL));
info("Select the red node");
const redNode = await getNodeFrontInFrame("div", "#same-origin", inspector);
await selectNode(redNode, inspector);
await selectNodeInFrames(["#same-origin", "div"], inspector);
info(
"Take a screenshot of the red div in the same origin iframe node and verify it looks as expected"
@ -32,9 +31,8 @@ add_task(async function() {
b: 0,
});
// info("Select the green node");
const greenNode = await getNodeFrontInFrame("div", "#remote", inspector);
await selectNode(greenNode, inspector);
info("Select the green node");
await selectNodeInFrames(["#remote", "div"], inspector);
info(
"Take a screenshot of the green div in the remote iframe node and verify it looks as expected"
);

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

@ -18,13 +18,11 @@ add_task(async function() {
await addNewRuleAndDismissEditor(inspector, view, "div", 1);
await addNewProperty(view, 1, "color", "red");
const innerFrameDiv1 = await getNodeFrontInFrame("div", "#frame1", inspector);
await selectNode(innerFrameDiv1, inspector);
await selectNodeInFrames(["#frame1", "div"], inspector);
await addNewRuleAndDismissEditor(inspector, view, "div", 1);
await addNewProperty(view, 1, "color", "blue");
const innerFrameDiv2 = await getNodeFrontInFrame("div", "#frame2", inspector);
await selectNode(innerFrameDiv2, inspector);
await selectNodeInFrames(["#frame2", "div"], inspector);
await addNewRuleAndDismissEditor(inspector, view, "div", 1);
await addNewProperty(view, 1, "color", "green");
});

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

@ -42,8 +42,7 @@ add_task(async function() {
);
info("Select the node from the remote iframe");
const iframeEl = await getNodeFrontInFrame("html", "iframe", inspector);
await selectNode(iframeEl, inspector);
await selectNodeInFrames(["iframe", "html"], inspector);
ok(
ruleViewHasColor("#0ff"),
@ -62,7 +61,7 @@ add_task(async function() {
await waitFor(() => ruleViewHasColor("#f00"));
info("Select the node from the remote iframe again");
await selectNode(iframeEl, inspector);
await selectNodeInFrames(["iframe", "html"], inspector);
await waitFor(() => ruleViewHasColor("#ff0"));
ok(true, "The simulation stopped on the remote iframe as well");

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

@ -9,7 +9,7 @@ const TEST_URL = URL_ROOT + "doc_inspector_delete-selected-node-01.html";
add_task(async function() {
const { inspector } = await openInspectorForURL(TEST_URL);
const span = await getNodeFrontInFrame("span", "iframe", inspector);
const span = await getNodeFrontInFrames(["iframe", "span"], inspector);
await selectNode(span, inspector);
info("Removing selected <span> element.");

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

@ -64,11 +64,10 @@ add_task(async function() {
);
info("Selecting an element inside iframe.");
const iframe = await getNodeFront("#deleteIframe", inspector);
const div = await getNodeFrontInFrame("#deleteInIframe", iframe, inspector);
await selectNode(div, inspector);
await selectNodeInFrames(["#deleteIframe", "#deleteInIframe"], inspector);
info("Deleting selected node via javascript.");
info("Deleting parent iframe node via javascript.");
const iframe = await getNodeFront("#deleteIframe", inspector);
await inspector.walker.removeNode(iframe);
info("Waiting for inspector to update.");

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

@ -10,11 +10,11 @@ const TEST_URL = URL_ROOT + "doc_inspector_delete-selected-node-01.html";
add_task(async function() {
const { inspector } = await openInspectorForURL(TEST_URL);
const iframe = await getNodeFront("iframe", inspector);
const node = await getNodeFrontInFrame("span", iframe, inspector);
await selectNode(node, inspector);
info("Select a node inside the iframe");
await selectNodeInFrames(["iframe", "span"], inspector);
info("Removing iframe.");
const iframe = await getNodeFront("iframe", inspector);
await inspector.walker.removeNode(iframe);
await inspector.selection.once("detached-front");

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

@ -27,9 +27,8 @@ async function testPolygonIframeMovePoint(config) {
info(`Turn on shapes highlighter for ${selector}`);
// Get a reference to the highlighter's target node inside the iframe.
const highlightedNode = await getNodeFrontInFrame(
selector,
"#frame",
const highlightedNode = await getNodeFrontInFrames(
["#frame", selector],
inspector
);
// Select the nested node so toggling of the shapes highlighter works from the rule view

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

@ -49,17 +49,7 @@ add_task(async function() {
await selectNode(inspector.walker.rootNode, inspector);
info("Selecting an element from the nested iframe directly");
const innerFrameFront = await getNodeFrontInFrame(
"iframe",
"iframe",
inspector
);
const innerFrameDivFront = await getNodeFrontInFrame(
"div",
innerFrameFront,
inspector
);
await selectNode(innerFrameDivFront, inspector);
await selectNodeInFrames(["iframe", "iframe", "div"], inspector);
is(
inspector.breadcrumbs.nodeHierarchy.length,

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

@ -56,7 +56,7 @@ add_task(async function() {
let contextNode;
if (inIframe) {
contextNode = await getNodeFrontInFrame("body", "iframe", inspector);
contextNode = await getNodeFrontInFrames(["iframe", "body"], inspector);
} else {
contextNode = await getNodeFront("body", inspector);
}

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

@ -26,7 +26,7 @@ add_task(async function() {
// Use context menu with root frame selected in toolbox
await testContextMenuWithinIframe(testActor, async inspector => {
return getNodeFrontInFrame("#in-frame", "iframe", inspector);
return getNodeFrontInFrames(["iframe", "#in-frame"], inspector);
});
// Use context menu with inner frame selected in toolbox

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

@ -16,22 +16,20 @@ const HTML = `
const TEST_URI = "data:text/html;charset=utf-8," + encodeURI(HTML);
add_task(async function() {
const { inspector, testActor } = await openInspectorForURL(TEST_URI);
const { inspector } = await openInspectorForURL(TEST_URI);
const nodeFront = await getNodeFrontInFrame("#in-frame", "iframe", inspector);
await selectNode(nodeFront, inspector);
await selectNodeInFrames(["iframe", "#in-frame"], inspector);
const markupLoaded = inspector.once("markuploaded");
info("Reloading page.");
await testActor.eval("location.reload()");
await navigateTo(TEST_URI);
info("Waiting for markupview to load after reload.");
await markupLoaded;
const reloadedNodeFront = await getNodeFrontInFrame(
"#in-frame",
"iframe",
const reloadedNodeFront = await getNodeFrontInFrames(
["iframe", "#in-frame"],
inspector
);

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

@ -39,8 +39,7 @@ add_task(async function() {
);
info("Select node inside iframe.");
const nodeFront = await getNodeFrontInFrame("#in-frame", "iframe", inspector);
await selectNode(nodeFront, inspector);
await selectNodeInFrames(["iframe", "#in-frame"], inspector);
const markupLoaded = inspector.once("markuploaded");

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

@ -283,66 +283,6 @@ var clickOnInspectMenuItem = async function(testActor, selector) {
return getActiveInspector();
};
/**
* Get the NodeFront for a node that matches a given css selector inside a
* given iframe.
* @param {String|NodeFront} selector
* @param {String|NodeFront} frameSelector A selector that matches the iframe
* the node is in
* @param {InspectorPanel} inspector The instance of InspectorPanel currently
* loaded in the toolbox
* @return {Promise} Resolves when the inspector is updated with the new node
*/
var getNodeFrontInFrame = async function(selector, frameSelector, inspector) {
let walker;
// If frameSelector is already a NodeFront, we can directly retrieve its walker
if (frameSelector._form) {
walker = frameSelector.walkerFront;
} else {
// The iframe could be remote, so we need to retrieve the associated target front.
const iframeBrowsingContextId = await SpecialPowers.spawn(
gBrowser.selectedTab.linkedBrowser,
[frameSelector],
function(innerFrameSelector) {
const el = content.document.querySelector(innerFrameSelector);
if (!el) {
return null;
}
return el.browsingContext.id;
}
);
if (!iframeBrowsingContextId) {
throw new Error(`Couldn't find an iframe matching "${frameSelector}"`);
}
const { descriptorFront } = inspector.inspectorFront.targetFront;
const watcherFront = await descriptorFront.getWatcher();
const target = await watcherFront.getBrowsingContextTarget(
iframeBrowsingContextId
);
const inspectorFront = await target.getFront("inspector");
walker = inspectorFront.walker;
}
let queryNode;
if (walker === inspector.inspectorFront.walker) {
// If the walker for the iframe is the same as the top-level target in the inspector,
// we need to retrieve the element from the iframe first children.
const iframe = await getNodeFront(frameSelector, inspector);
const { nodes } = await walker.children(iframe);
queryNode = nodes[0];
} else {
// whereas if we have a dedicated target for the iframe, we can directly query from
// the walker root node.
queryNode = walker.rootNode;
}
return walker.querySelector(queryNode, selector);
};
/**
* Get the NodeFront for the document node inside a given iframe.
*
@ -677,9 +617,8 @@ const getHighlighterHelperFor = type =>
show: async function(selector = ":root", options, frameSelector = null) {
if (frameSelector) {
highlightedNode = await getNodeFrontInFrame(
selector,
frameSelector,
highlightedNode = await getNodeFrontInFrames(
[frameSelector, selector],
inspector
);
} else {

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

@ -240,6 +240,61 @@ var selectNode = async function(
await updated;
};
/**
* Get the NodeFront for a node that matches a given css selector inside a
* given iframe.
*
* @param {Array} selectors
* Arrays of CSS selectors from the root document to the node.
* The last CSS selector of the array is for the node in its frame doc.
* The before-last CSS selector is for the frame in its parent frame, etc...
* Ex: ["frame.first-frame", ..., "frame.last-frame", ".target-node"]
* @param {InspectorPanel} inspector
* See `selectNode`
* @return {NodeFront} Resolves the corresponding node front.
*/
async function getNodeFrontInFrames(selectors, inspector) {
let walker = inspector.walker;
let rootNode = walker.rootNode;
// Extract the last selector from the provided array of selectors.
const nodeSelector = selectors.pop();
// Remaining selectors should all be frame selectors. Renaming for clarity.
const frameSelectors = selectors;
info("Loop through all frame selectors");
for (const frameSelector of frameSelectors) {
const url = walker.targetFront.url;
info(`Find the frame element for selector ${frameSelector} in ${url}`);
const frameFront = await walker.querySelector(rootNode, frameSelector);
// For a remote frame, connect to the corresponding frame target.
// Otherwise, reuse the current targetFront.
let frameTarget = frameFront.targetFront;
if (frameFront.remoteFrame) {
info("Connect to remote frame and retrieve the targetFront");
frameTarget = await frameFront.connectToRemoteFrame();
}
walker = (await frameTarget.getFront("inspector")).walker;
if (frameFront.remoteFrame) {
// For remote frames or browser elements, use the walker's rootNode.
rootNode = walker.rootNode;
} else {
// For same-process frames, select the document front as the root node.
// It is a different node from the walker's rootNode.
info("Retrieve the children of the frame to find the document node");
const { nodes } = await walker.children(frameFront);
rootNode = nodes.find(n => n.nodeType === Node.DOCUMENT_NODE);
}
}
return walker.querySelector(rootNode, nodeSelector);
}
/**
* Helper to select a node in the markup-view, in a nested tree of
* frames/browser elements. The iframes can either be remote or same-process.
@ -266,46 +321,7 @@ async function selectNodeInFrames(
reason = "test",
isSlotted
) {
let walker = inspector.walker;
let rootNode = walker.rootNode;
// Extract the last selector from the provided array of selectors.
const nodeSelector = selectors.pop();
// Remaining selectors should all be frame selectors. Renaming for clarity.
const frameSelectors = selectors;
info("Loop through all frame selectors");
for (const frameSelector of frameSelectors) {
const url = walker.targetFront.url;
info(`Find the frame element for selector ${frameSelector} in ${url}`);
const frameFront = await walker.querySelector(rootNode, frameSelector);
await selectNode(frameFront, inspector);
// For a remote frame, connect to the corresponding frame target.
// Otherwise, reuse the current targetFront.
let frameTarget = frameFront.targetFront;
if (frameFront.remoteFrame) {
info("Connect to remote frame and retrieve the targetFront");
frameTarget = await frameFront.connectToRemoteFrame();
}
walker = (await frameTarget.getFront("inspector")).walker;
if (frameFront.remoteFrame) {
// For remote frames or browser elements, use the walker's rootNode.
rootNode = walker.rootNode;
} else {
// For same-process frames, select the document front as the root node.
// It is a different node from the walker's rootNode.
info("Retrieve the children of the frame to find the document node");
const { nodes } = await walker.children(frameFront);
rootNode = nodes.find(n => n.nodeType === Node.DOCUMENT_NODE);
}
}
const nodeFront = await walker.querySelector(rootNode, nodeSelector);
const nodeFront = await getNodeFrontInFrames(selectors, inspector);
await selectNode(nodeFront, inspector, reason, isSlotted);
return nodeFront;
}