From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- ...r_ext_devtools_inspectedWindow_eval_bindings.js | 266 +++++++++++++++++++++ 1 file changed, 266 insertions(+) create mode 100644 browser/components/extensions/test/browser/browser_ext_devtools_inspectedWindow_eval_bindings.js (limited to 'browser/components/extensions/test/browser/browser_ext_devtools_inspectedWindow_eval_bindings.js') diff --git a/browser/components/extensions/test/browser/browser_ext_devtools_inspectedWindow_eval_bindings.js b/browser/components/extensions/test/browser/browser_ext_devtools_inspectedWindow_eval_bindings.js new file mode 100644 index 0000000000..f85660c813 --- /dev/null +++ b/browser/components/extensions/test/browser/browser_ext_devtools_inspectedWindow_eval_bindings.js @@ -0,0 +1,266 @@ +/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set sts=2 sw=2 et tw=80: */ +"use strict"; + +loadTestSubscript("head_devtools.js"); + +const BASE_URL = + "http://mochi.test:8888/browser/browser/components/extensions/test/browser/"; + +/** + * this test file ensures that: + * + * - devtools.inspectedWindow.eval provides the expected $0 and inspect bindings + */ +add_task(async function test_devtools_inspectedWindow_eval_bindings() { + const TEST_TARGET_URL = `${BASE_URL}/file_inspectedwindow_eval.html`; + + let tab = await BrowserTestUtils.openNewForegroundTab( + gBrowser, + TEST_TARGET_URL + ); + + function devtools_page() { + browser.test.onMessage.addListener(async (msg, ...args) => { + if (msg !== "inspectedWindow-eval-request") { + browser.test.fail(`Unexpected test message received: ${msg}`); + return; + } + + try { + const [evalResult, errorResult] = + await browser.devtools.inspectedWindow.eval(...args); + browser.test.sendMessage("inspectedWindow-eval-result", { + evalResult, + errorResult, + }); + } catch (err) { + browser.test.sendMessage("inspectedWindow-eval-result"); + browser.test.fail(`Error: ${err} :: ${err.stack}`); + } + }); + browser.test.sendMessage("devtools-page-loaded"); + } + + let extension = ExtensionTestUtils.loadExtension({ + manifest: { + devtools_page: "devtools_page.html", + }, + files: { + "devtools_page.html": ` + + + + + + + + `, + "devtools_page.js": devtools_page, + }, + }); + + await extension.startup(); + + const toolbox = await openToolboxForTab(tab); + await extension.awaitMessage("devtools-page-loaded"); + + // Test $0 binding with no selected node + info("Test inspectedWindow.eval $0 binding with no selected node"); + + const evalNoSelectedNodePromise = extension.awaitMessage( + `inspectedWindow-eval-result` + ); + extension.sendMessage(`inspectedWindow-eval-request`, "$0"); + const evalNoSelectedNodeResult = await evalNoSelectedNodePromise; + + Assert.deepEqual( + evalNoSelectedNodeResult, + { evalResult: undefined, errorResult: undefined }, + "Got the expected eval result" + ); + + // Test $0 binding with a selected node in the inspector. + + await openToolboxForTab(tab, "inspector"); + + info( + "Test inspectedWindow.eval $0 binding with a selected node in the inspector" + ); + + const evalSelectedNodePromise = extension.awaitMessage( + `inspectedWindow-eval-result` + ); + extension.sendMessage(`inspectedWindow-eval-request`, "$0 && $0.tagName"); + const evalSelectedNodeResult = await evalSelectedNodePromise; + + Assert.deepEqual( + evalSelectedNodeResult, + { evalResult: "BODY", errorResult: undefined }, + "Got the expected eval result" + ); + + // Test that inspect($0) switch the developer toolbox to the inspector. + + await openToolboxForTab(tab, TOOLBOX_BLANK_PANEL_ID); + + const inspectorPanelSelectedPromise = (async () => { + const toolId = await toolbox.once("select"); + + if (toolId === "inspector") { + info("Toolbox has been switched to the inspector as expected"); + const selectedNodeName = + toolbox.selection.nodeFront && + toolbox.selection.nodeFront._form.nodeName; + is( + selectedNodeName, + "A", + "The expected DOM node has been selected in the inspector" + ); + } else { + throw new Error( + `inspector panel expected, ${toolId} has been selected instead` + ); + } + })(); + + info("Test inspectedWindow.eval inspect() binding called for a DOM element"); + extension.sendMessage( + `inspectedWindow-eval-request`, + "inspect(document.querySelector('a#link-to-inspect'))" + ); + await extension.awaitMessage(`inspectedWindow-eval-result`); + + info( + "Wait for the toolbox to switch to the inspector and the expected node has been selected" + ); + await inspectorPanelSelectedPromise; + + function expectedSourceSelected(sourceFilename, sourceLine) { + return () => { + const dbg = toolbox.getPanel("jsdebugger"); + const selectedLocation = dbg._selectors.getSelectedLocation( + dbg._getState() + ); + + if (!selectedLocation) { + return false; + } + + return ( + selectedLocation.sourceId.includes(sourceFilename) && + selectedLocation.line == sourceLine + ); + }; + } + + info("Test inspectedWindow.eval inspect() binding called for a function"); + + const debuggerPanelSelectedPromise = (async () => { + const toolId = await toolbox.once("select"); + + if (toolId === "jsdebugger") { + info("Toolbox has been switched to the jsdebugger as expected"); + } else { + throw new Error( + `jsdebugger panel expected, ${toolId} has been selected instead` + ); + } + })(); + + extension.sendMessage( + `inspectedWindow-eval-request`, + "inspect(test_inspect_function)" + ); + await extension.awaitMessage(`inspectedWindow-eval-result`); + await debuggerPanelSelectedPromise; + + await BrowserTestUtils.waitForCondition( + expectedSourceSelected("file_inspectedwindow_eval.html", 9), + "Wait the expected function to be selected in the jsdebugger panel" + ); + + info("Test inspectedWindow.eval inspect() bound function"); + + extension.sendMessage( + `inspectedWindow-eval-request`, + "inspect(test_bound_function)" + ); + await extension.awaitMessage(`inspectedWindow-eval-result`); + + await BrowserTestUtils.waitForCondition( + expectedSourceSelected("file_inspectedwindow_eval.html", 15), + "Wait the expected function to be selected in the jsdebugger panel" + ); + + info("Test inspectedWindow.eval inspect() binding called for a JS object"); + + const splitPanelOpenedPromise = (async () => { + await toolbox.once("split-console"); + const { hud } = toolbox.getPanel("webconsole"); + + // Wait for the message to appear on the console. + const messageNode = await new Promise(resolve => { + hud.ui.on("new-messages", function onThisMessage(messages) { + for (let m of messages) { + resolve(m.node); + hud.ui.off("new-messages", onThisMessage); + return; + } + }); + }); + let objectInspectors = [...messageNode.querySelectorAll(".tree")]; + is( + objectInspectors.length, + 1, + "There is the expected number of object inspectors" + ); + + // We need to wait for the object to be expanded so we don't call the server on a closed connection. + const [oi] = objectInspectors; + let nodes = oi.querySelectorAll(".node"); + + ok(nodes.length >= 1, "The object preview is rendered as expected"); + + // The tree can still be collapsed since the properties are fetched asynchronously. + if (nodes.length === 1) { + info("Waiting for the object properties to be displayed"); + // If this is the case, we wait for the properties to be fetched and displayed. + await new Promise(resolve => { + const observer = new MutationObserver(mutations => { + resolve(); + observer.disconnect(); + }); + observer.observe(oi, { childList: true }); + }); + + // Retrieve the new nodes. + nodes = oi.querySelectorAll(".node"); + } + + // We should have 3 nodes : + // ▼ Object { testkey: "testvalue" } + // | testkey: "testvalue" + // | ▶︎ __proto__: Object { … } + is(nodes.length, 3, "The object preview has the expected number of nodes"); + })(); + + const inspectJSObjectPromise = extension.awaitMessage( + `inspectedWindow-eval-result` + ); + extension.sendMessage( + `inspectedWindow-eval-request`, + "inspect({testkey: 'testvalue'})" + ); + await inspectJSObjectPromise; + + info("Wait for the split console to be opened and the JS object inspected"); + await splitPanelOpenedPromise; + info("Split console has been opened as expected"); + + await closeToolboxForTab(tab); + + await extension.unload(); + + BrowserTestUtils.removeTab(tab); +}); -- cgit v1.2.3