Bug 1442604 - Add tests for the select and autocompletion popups used in an extension devtools panels.
MozReview-Commit-ID: 5ov2YaeQV8V
--- a/browser/components/extensions/parent/ext-devtools-panels.js
+++ b/browser/components/extensions/parent/ext-devtools-panels.js
@@ -87,17 +87,17 @@ class ParentDevToolsPanel {
isTargetSupported: target => target.isLocalTab,
build: (window, toolbox) => {
if (toolbox !== this.toolbox) {
throw new Error("Unexpected toolbox received on addAdditionalTool build property");
}
const destroy = this.buildPanel(window);
- return {toolbox, destroy};
+ return {toolbox, destroy, panelWindow: window};
},
});
this.panelAdded = true;
}
buildPanel(window) {
const {toolbox} = this;
--- a/browser/components/extensions/test/browser/browser-common.ini
+++ b/browser/components/extensions/test/browser/browser-common.ini
@@ -84,16 +84,17 @@ skip-if = (os == 'win' && !debug) # bug
[browser_ext_contextMenus_urlPatterns.js]
[browser_ext_currentWindow.js]
[browser_ext_devtools_inspectedWindow.js]
[browser_ext_devtools_inspectedWindow_eval_bindings.js]
[browser_ext_devtools_inspectedWindow_reload.js]
[browser_ext_devtools_network.js]
[browser_ext_devtools_page.js]
[browser_ext_devtools_panel.js]
+[browser_ext_devtools_panel_dropdowns.js]
[browser_ext_devtools_panels_elements.js]
[browser_ext_devtools_panels_elements_sidebar.js]
support-files =
../../../../../devtools/client/inspector/extensions/test/head_devtools_inspector_sidebar.js
[browser_ext_devtools_theme.js]
[browser_ext_find.js]
[browser_ext_geckoProfiler_symbolicate.js]
[browser_ext_getViews.js]
new file mode 100644
--- /dev/null
+++ b/browser/components/extensions/test/browser/browser_ext_devtools_panel_dropdowns.js
@@ -0,0 +1,179 @@
+/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set sts=2 sw=2 et tw=80: */
+"use strict";
+
+Services.scriptloader.loadSubScript(new URL("head_devtools.js", gTestPath).href,
+ this);
+
+/**
+ * This test file ensures that the WebExtensions devtools panels support:
+ *
+ * - select dropdown
+ * - autocompletion dropdown
+ */
+
+let extension;
+let panelWindow;
+let panelBrowser;
+let tab;
+
+async function waitForExpectedValue({selector, value}) {
+ const el = this.content.document.querySelector(selector);
+ await ContentTaskUtils.waitForCondition(
+ () => el.value === value,
+ `Wait "${selector}" to be set to the expected value`);
+}
+
+async function ensureElementFocused(panelBrowser, elementSelector) {
+ panelBrowser.focus();
+ // Ensure that the devtools panel is focused.
+ await ContentTask.spawn(panelBrowser, {
+ selector: elementSelector,
+ }, ({selector}) => {
+ this.content.document.querySelector(selector).focus();
+ });
+}
+
+// Install the test extension that provides the devtools panel where the
+// the dropdowns tests will run on.
+add_task(async function setup_extension_with_devtools_panel() {
+ tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "http://mochi.test:8888/");
+
+ async function devtools_page() {
+ try {
+ await browser.devtools.panels.create(
+ "Test Panel Create", "fake-icon.png", "devtools_panel.html"
+ );
+ browser.test.notifyPass("devtools_panel_created");
+ } catch (err) {
+ // Make the test able to fail fast when it is going to be a failure.
+ browser.test.notifyPass("devtools_panel_created");
+ throw err;
+ }
+ }
+
+ function devtools_panel() {
+ browser.test.sendMessage("devtools_panel_loaded");
+ }
+
+ const panelHTMLContent = (`
+ <div>
+ <select id="test-select">
+ <option value="1" default>value 1</option>
+ <option value="2" default>value 2</option>
+ <option value="3" default>value 3</option>
+ </select>
+ <datalist id="autocompletion-values">
+ <option value="autocomplete value 1" />
+ <option value="autocomplete value 2" />
+ <option value="autocomplete value 3" />
+ </datalist>
+ <input id="test-autocompletion" type="text" list="autocompletion-values" />
+ <p>
+ <a href="http://example.com#test-link">a link</a>
+ </p>
+ </div>`);
+
+ extension = ExtensionTestUtils.loadExtension({
+ manifest: {
+ devtools_page: "devtools_page.html",
+ },
+ files: {
+ "devtools_page.html": createPage("devtools_page.js"),
+ "devtools_page.js": devtools_page,
+ "devtools_panel.html": createPage("devtools_panel.js", panelHTMLContent),
+ "devtools_panel.js": devtools_panel,
+ },
+ });
+
+ await extension.startup();
+
+ // Get the devtools panel id from the first item in the toolbox additional tools array.
+ const getPanelId = (toolbox) => {
+ let toolboxAdditionalTools = toolbox.getAdditionalTools();
+ is(toolboxAdditionalTools.length, 1,
+ "Got the expected number of toolbox specific panel registered.");
+ return toolboxAdditionalTools[0].id;
+ };
+
+ // Wait that the devtools_page has created its devtools panel and retrieve its
+ // panel id.
+ let {toolbox, target} = await openToolboxForTab(tab);
+
+ await extension.awaitFinish("devtools_panel_created");
+ let panelId = getPanelId(toolbox);
+
+ // Load the extension devtools panel.
+ await gDevTools.showToolbox(target, panelId);
+ await extension.awaitMessage("devtools_panel_loaded");
+
+ const panel = await toolbox.getPanel(panelId);
+
+ panelWindow = panel.panelWindow;
+ panelBrowser = panelWindow.document.getElementById("webext-panels-browser");
+});
+
+add_task(async function test_select_dropdown() {
+ // Set dom.select_popup_in_parent.enabled to true simplify the tests
+ // because we can use the same strategy to wait the different
+ // dropdown's popups to be opened (in both extension oop and non-oop modes).
+ SpecialPowers.pushPrefEnv({
+ "set": [["dom.select_popup_in_parent.enabled", true]],
+ });
+ registerCleanupFunction(() => SpecialPowers.popPrefEnv());
+
+ const menulist = panelWindow.document.getElementById("ContentSelectDropdown");
+ const selectPopup = menulist.menupopup;
+
+ info("Click the select and wait the dropdown to be shown");
+ const oncePopupOpen = BrowserTestUtils.waitForEvent(selectPopup, "popupshown", false);
+
+ // Open the select dropdown by pressing space while the select element is focused.
+ await ensureElementFocused(panelBrowser, "#test-select");
+ EventUtils.synthesizeKey("VK_SPACE");
+
+ await oncePopupOpen;
+
+ info("select dropdown opened, select the second option");
+ EventUtils.synthesizeKey("KEY_ArrowDown");
+ EventUtils.synthesizeKey("KEY_Enter");
+
+ await ContentTask.spawn(panelBrowser, {
+ selector: "#test-select",
+ value: "2",
+ }, waitForExpectedValue);
+});
+
+add_task(async function test_autocompletion_dropdown() {
+ const autocompletePopup = panelWindow.document.getElementById("PopupAutoComplete");
+
+ info("Trigger the autocompletion on the input element and wait the dropdown to be shown");
+ const oncePopupOpen = BrowserTestUtils.waitForEvent(autocompletePopup, "popupshown", false);
+
+ await ensureElementFocused(panelBrowser, "#test-autocompletion");
+
+ // Click two times the input lement to open the autocompletion drop down).
+ BrowserTestUtils.synthesizeMouseAtCenter("#test-autocompletion", {}, panelBrowser);
+ BrowserTestUtils.synthesizeMouseAtCenter("#test-autocompletion", {}, panelBrowser);
+
+ await oncePopupOpen;
+
+ info("autocompletion dropdown opened, select found option");
+ EventUtils.synthesizeKey("VK_DOWN", {}, panelWindow);
+ EventUtils.synthesizeKey("VK_DOWN", {}, panelWindow);
+ EventUtils.synthesizeKey("VK_DOWN", {}, panelWindow);
+ EventUtils.synthesizeKey("VK_RETURN", {}, panelWindow);
+
+ await ContentTask.spawn(panelBrowser, {
+ selector: "#test-autocompletion",
+ value: "autocomplete value 3",
+ }, waitForExpectedValue);
+});
+
+add_task(async function teardown_test_extension_with_devtools_panel() {
+ await closeToolboxForTab(tab);
+
+ await extension.unload();
+
+ BrowserTestUtils.removeTab(tab);
+});