browser_inspector_inspect_node_contextmenu.js (5374B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 "use strict"; 6 7 // Tests for inspecting iframes and frames in browser context menu 8 const IFRAME_URI = `data:text/html;charset=utf-8,${encodeURI( 9 `<div id="in-iframe">div in the iframe</div>` 10 )}`; 11 const TEST_IFRAME_DOC_URI = `data:text/html;charset=utf-8,${encodeURI(` 12 <div id="salutation">Salution in top document</div> 13 <iframe src="${IFRAME_URI}"></iframe>`)}`; 14 15 // <frameset> acts as the body element, so we can't use them in a document with other elements 16 // and have to set a dedicated document so we can test them. 17 const SAME_ORIGIN_FRAME_URI = `https://example.com/document-builder.sjs?html=<h2 id=in-same-origin-frame>h2 in the same origin frame</h2>`; 18 const REMOTE_ORIGIN_FRAME_URI = `https://example.org/document-builder.sjs?html=<h3 id=in-remote-frame>h3 in the remote frame</h3>`; 19 const TEST_FRAME_DOC_URI = `https://example.com/document-builder.sjs?html=${encodeURI(` 20 <frameset cols="50%,50%"> 21 <frame class=same-origin src="${SAME_ORIGIN_FRAME_URI}"></frame> 22 <frame class=remote src="${REMOTE_ORIGIN_FRAME_URI}"></frame> 23 </frameset>`)}`; 24 25 add_task(async function () { 26 await pushPref("devtools.command-button-frames.enabled", true); 27 await addTab(TEST_IFRAME_DOC_URI); 28 info( 29 "Test inspecting element in <iframe> with top document selected in the frame picker" 30 ); 31 await testContextMenuWithinFrame({ 32 selector: ["iframe", "#in-iframe"], 33 nodeFrontGetter: inspector => 34 getNodeFrontInFrames(["iframe", "#in-iframe"], inspector), 35 }); 36 37 info( 38 "Test inspecting element in <iframe> with iframe document selected in the frame picker" 39 ); 40 await changeToolboxToFrame(IFRAME_URI, 2); 41 await testContextMenuWithinFrame({ 42 selector: ["iframe", "#in-iframe"], 43 nodeFrontGetter: inspector => getNodeFront("#in-iframe", inspector), 44 }); 45 await changeToolboxToFrame(TEST_IFRAME_DOC_URI, 2); 46 47 await navigateTo(TEST_FRAME_DOC_URI); 48 49 info( 50 "Test inspecting element in same origin <frame> with top document selected in the frame picker" 51 ); 52 await testContextMenuWithinFrame({ 53 selector: ["frame.same-origin", "#in-same-origin-frame"], 54 nodeFrontGetter: inspector => 55 getNodeFrontInFrames( 56 ["frame.same-origin", "#in-same-origin-frame"], 57 inspector 58 ), 59 }); 60 61 info( 62 "Test inspecting element in remote <frame> with top document selected in the frame picker" 63 ); 64 await testContextMenuWithinFrame({ 65 selector: ["frame.remote", "#in-remote-frame"], 66 nodeFrontGetter: inspector => 67 getNodeFrontInFrames(["frame.remote", "#in-remote-frame"], inspector), 68 }); 69 70 info( 71 "Test inspecting element in <frame> with frame document selected in the frame picker" 72 ); 73 await changeToolboxToFrame(SAME_ORIGIN_FRAME_URI, 3); 74 await testContextMenuWithinFrame({ 75 selector: ["frame.same-origin", "#in-same-origin-frame"], 76 nodeFrontGetter: inspector => 77 getNodeFront("#in-same-origin-frame", inspector), 78 }); 79 }); 80 81 /** 82 * Pick a given element on the page with the 'Inspect Element' context menu entry and check 83 * that the expected node is selected in the markup view. 84 * 85 * @param {object} options 86 * @param {Array<string>} options.selector: The selector of the element in the frame we 87 * want to select 88 * @param {Function} options.nodeFrontGetter: A function that will be executed to retrieve 89 * the nodeFront that should be selected as a result of the 'Inspect Element' action. 90 */ 91 async function testContextMenuWithinFrame({ selector, nodeFrontGetter }) { 92 info( 93 `Opening inspector via 'Inspect Element' context menu on ${JSON.stringify( 94 selector 95 )}` 96 ); 97 await clickOnInspectMenuItem(selector); 98 99 info("Checking inspector state."); 100 const inspector = getActiveInspector(); 101 const nodeFront = await nodeFrontGetter(inspector); 102 103 is( 104 inspector.selection.nodeFront, 105 nodeFront, 106 "Right node is selected in the markup view" 107 ); 108 } 109 110 /** 111 * Select a specific document in the toolbox frame picker 112 * 113 * @param {string} frameUrl: The frame URL to select 114 * @param {number} expectedFramesCount: The number of frames that should be displayed in 115 * the frame picker 116 */ 117 async function changeToolboxToFrame(frameUrl, expectedFramesCount) { 118 const { toolbox } = getActiveInspector(); 119 120 const btn = toolbox.doc.getElementById("command-button-frames"); 121 const panel = toolbox.doc.getElementById("command-button-frames-panel"); 122 btn.click(); 123 ok(panel, "popup panel has created."); 124 await waitUntil(() => panel.classList.contains("tooltip-visible")); 125 126 info("Select the iframe in the frame list."); 127 const menuList = toolbox.doc.getElementById("toolbox-frame-menu"); 128 const frames = Array.from(menuList.querySelectorAll(".command")); 129 is(frames.length, expectedFramesCount, "Two frames shown in the switcher"); 130 131 const innerFrameButton = frames.find( 132 frame => frame.querySelector(".label").textContent === frameUrl 133 ); 134 ok(innerFrameButton, `Found frame button for inner frame "${frameUrl}"`); 135 136 const newRoot = toolbox.getPanel("inspector").once("new-root"); 137 info(`Switch toolbox to inner frame "${frameUrl}"`); 138 innerFrameButton.click(); 139 await newRoot; 140 }