diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /browser/components/aboutlogins/tests/chrome/test_menu_button.html | |
parent | Initial commit. (diff) | |
download | firefox-esr-upstream.tar.xz firefox-esr-upstream.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'browser/components/aboutlogins/tests/chrome/test_menu_button.html')
-rw-r--r-- | browser/components/aboutlogins/tests/chrome/test_menu_button.html | 260 |
1 files changed, 260 insertions, 0 deletions
diff --git a/browser/components/aboutlogins/tests/chrome/test_menu_button.html b/browser/components/aboutlogins/tests/chrome/test_menu_button.html new file mode 100644 index 0000000000..2beede09f1 --- /dev/null +++ b/browser/components/aboutlogins/tests/chrome/test_menu_button.html @@ -0,0 +1,260 @@ +<!DOCTYPE HTML> +<html> +<!-- +Test the menu-button component +--> +<head> + <meta charset="utf-8"> + <title>Test the menu-button component</title> + <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script> + <script type="module" src="chrome://browser/content/aboutlogins/components/menu-button.mjs"></script> + <script src="aboutlogins_common.js"></script> + + <link rel="stylesheet" href="/tests/SimpleTest/test.css"/> +</head> +<body> + <p id="display"> + </p> +<div id="content" style="display: none"> + <iframe id="templateFrame" src="chrome://browser/content/aboutlogins/aboutLogins.html" + sandbox="allow-same-origin"></iframe> +</div> +<pre id="test"> +</pre> +<script> +/** Test the menu-button component **/ + +let gMenuButton; +add_setup(async () => { + let templateFrame = document.getElementById("templateFrame"); + let displayEl = document.getElementById("display"); + await importDependencies(templateFrame, displayEl); + + gMenuButton = document.createElement("menu-button"); + displayEl.appendChild(gMenuButton); + gMenuButton.style.marginInlineStart = "100px"; + + isnot(document.activeElement, gMenuButton, "menu-button should not be focused by default"); + while (document.activeElement != gMenuButton) { + sendKey("TAB"); + await new Promise(resolve => requestAnimationFrame(resolve)); + } +}); + +add_task(async function test_menu_click_button () { + let menu = gMenuButton.shadowRoot.querySelector(".menu"); + let menuButton = gMenuButton.shadowRoot.querySelector(".menu-button"); + ok(menu.hidden, "menu should be hidden before being clicked"); + await synthesizeMouseAtCenter(menuButton, {}); + await new Promise(resolve => requestAnimationFrame(resolve)); + ok(!menu.hidden, "menu should be visible after clicked"); + + let menuListSeparators = gMenuButton.shadowRoot.querySelectorAll(".menuitem-separator"); + await synthesizeMouseAtCenter(menuListSeparators[0], {}); + await new Promise(resolve => requestAnimationFrame(resolve)); + ok(!menu.hidden, "menu should still be visible after menu separator has been clicked"); + + let menuListButtons = gMenuButton.shadowRoot.querySelectorAll(".menuitem-button"); + await synthesizeMouseAtCenter(menuListButtons[0], {}); + await new Promise(resolve => requestAnimationFrame(resolve)); + ok(menu.hidden, "menu should be hidden after a button has been clicked"); +}); + +add_task(async function test_menu_click_outside () { + let menu = gMenuButton.shadowRoot.querySelector(".menu"); + let menuButton = gMenuButton.shadowRoot.querySelector(".menu-button"); + ok(menu.hidden, "menu should be hidden before being clicked"); + await synthesizeMouseAtCenter(menuButton, {}); + await new Promise(resolve => requestAnimationFrame(resolve)); + ok(!menu.hidden, "menu should be visible after clicked"); + + let menuListSeparators = gMenuButton.shadowRoot.querySelectorAll(".menuitem-separator"); + await synthesizeMouseAtCenter(menuListSeparators[0], {}); + await new Promise(resolve => requestAnimationFrame(resolve)); + ok(!menu.hidden, "menu should still be visible after menu separator has been clicked"); + + let outsideEl = document.getElementById("test"); + await synthesizeMouseAtCenter(outsideEl, {}); + await new Promise(resolve => requestAnimationFrame(resolve)); + ok(menu.hidden, "menu should be hidden after a click outside of the menu has been clicked"); + + for (let key of ["KEY_ArrowDown", "KEY_ArrowUp"]) { + synthesizeKey(key); + await new Promise(resolve => requestAnimationFrame(resolve)); + ok(menu.hidden, `menu should still be hidden when ${key} is entered`); + } +}); + +add_task(async function test_menu_esc_after_click_disabled_item () { + let menu = gMenuButton.shadowRoot.querySelector(".menu"); + let menuButton = gMenuButton.shadowRoot.querySelector(".menu-button"); + ok(menu.hidden, "menu should be hidden before being clicked"); + await synthesizeMouseAtCenter(menuButton, {}); + await new Promise(resolve => requestAnimationFrame(resolve)); + ok(!menu.hidden, "menu should be visible after clicked"); + + let menuListSeparators = gMenuButton.shadowRoot.querySelectorAll(".menuitem-separator"); + await synthesizeMouseAtCenter(menuListSeparators[0], {}); + await new Promise(resolve => requestAnimationFrame(resolve)); + ok(!menu.hidden, "menu should still be visible after menu separator has been clicked"); + + sendKey("ESCAPE"); + await new Promise(resolve => requestAnimationFrame(resolve)); + ok(menu.hidden, "menu should be hidden after pressing 'escape'"); +}); + +add_task(async function test_menu_open_close() { + is(document.activeElement, gMenuButton, "menu-button should be focused to start the test"); + + let menu = gMenuButton.shadowRoot.querySelector(".menu"); + is(true, menu.hidden, "menu should be hidden before pressing 'space'"); + sendKey("SPACE"); + await new Promise(resolve => requestAnimationFrame(resolve)); + ok(!menu.hidden, "menu should be visible after pressing 'space'"); + + sendKey("ESCAPE"); + await new Promise(resolve => requestAnimationFrame(resolve)); + ok(menu.hidden, "menu should be hidden after pressing 'escape'"); + is(gMenuButton.shadowRoot.activeElement, gMenuButton.shadowRoot.querySelector(".menu-button"), + "the .menu-button should be focused after closing the menu via keyboard"); + + sendKey("RETURN"); + let firstVisibleItem = gMenuButton.shadowRoot.querySelector(".menuitem-button:not([hidden])"); + await SimpleTest.promiseWaitForCondition(() => firstVisibleItem.matches(":focus"), + "waiting for firstVisibleItem to get focus"); + + ok(!menu.hidden, "menu should be visible after pressing 'return'"); + ok(firstVisibleItem.matches(":focus"), "firstVisibleItem should be focused after opening popup"); + + synthesizeKey("VK_TAB", { shiftKey: true }); + await SimpleTest.promiseWaitForCondition(() => !firstVisibleItem.matches(":focus"), + "waiting for firstVisibleItem to lose focus"); + ok(!firstVisibleItem.matches(":focus"), "firstVisibleItem should lose focus after tabbing away from it"); + sendKey("TAB"); + await SimpleTest.promiseWaitForCondition(() => firstVisibleItem.matches(":focus"), + "waiting for firstVisibleItem to get focus again"); + ok(firstVisibleItem.matches(":focus"), "firstVisibleItem should be focused after tabbing to it again"); + if (SpecialPowers.getBoolPref("signon.management.page.fileImport.enabled")) { + sendKey("TAB"); // Import from file + } + sendKey("TAB"); // Export + sendKey("TAB"); // Remove All Logins + + if (navigator.platform == "Win32" || navigator.platform == "MacIntel") { + // The Import menuitem is only visible on Windows/macOS, where we will need another Tab + // press to get to the Preferences item. + let preferencesItem = gMenuButton.shadowRoot.querySelector(".menuitem-preferences"); + sendKey("DOWN"); + await SimpleTest.promiseWaitForCondition(() => preferencesItem.matches(":focus"), + "waiting for preferencesItem to gain focus"); + ok(preferencesItem.matches(":focus"), `.menuitem-preferences should be now be focused (DOWN)`); + sendKey("UP"); + await SimpleTest.promiseWaitForCondition(() => !preferencesItem.matches(":focus"), + `waiting for preferencesItem to lose focus (UP)`); + ok(!preferencesItem.matches(":focus"), `.menuitem-preferences should lose focus after pressing up`); + + sendKey("TAB"); + await SimpleTest.promiseWaitForCondition(() => preferencesItem.matches(":focus"), + "waiting for preferencesItem to get focus"); + ok(preferencesItem.matches(":focus"), ".menuitem-preferences should be focused after tabbing to it"); + } + + let openPreferencesEvent = null; + ok(!menu.hidden, "menu should be visible before pressing 'space' on .menuitem-preferences"); + window.addEventListener( + "AboutLoginsOpenPreferences", + event => openPreferencesEvent = event, + {once: true} + ); + sendKey("SPACE"); + ok(openPreferencesEvent, "AboutLoginsOpenPreferences event should be dispatched after pressing 'space' on .menuitem-preferences"); + ok(menu.hidden, "menu should be hidden after pressing 'space' on .menuitem-preferences"); + + // Clean up task + sendKey("TAB"); + synthesizeKey("VK_TAB", { shiftKey: true }); +}); + +add_task(async function test_menu_keyboard_cycling() { + function waitForElementFocus(selector) { + return SimpleTest.promiseWaitForCondition( + () => gMenuButton.shadowRoot.querySelector(selector).matches(":focus"), + `waiting for ${selector} to be focused` + ); + } + + function getFocusedMenuItem() { + return gMenuButton.shadowRoot.querySelector(".menuitem-button:focus"); + } + + let allItems = [ + "menuitem-export", + "menuitem-remove-all-logins", + "menuitem-preferences", + "menuitem-help", + ]; + if (SpecialPowers.getBoolPref("signon.management.page.fileImport.enabled")) { + allItems = ["menuitem-import-file", ...allItems]; + } + if (navigator.platform == "Win32" || navigator.platform == "MacIntel") { + allItems = ["menuitem-import-browser", ...allItems]; + } + + let menu = gMenuButton.shadowRoot.querySelector(".menu"); + + is(document.activeElement, gMenuButton, "menu-button should be focused to start the test"); + is(true, menu.hidden, "menu should be hidden before pressing 'space'"); + + sendKey("RETURN"); + + await SimpleTest.promiseWaitForCondition(() => !menu.hidden, "waiting for menu to show"); + + ok(!menu.hidden, "menu should be visible after pressing 'enter'"); + + for (let item of allItems) { + await waitForElementFocus("." + item); + ok( + getFocusedMenuItem().classList.contains(item), + `.${item} should be selected after key is pressed` + ); + sendKey("DOWN"); + } + + + await waitForElementFocus("." + allItems[0]); + ok( + getFocusedMenuItem().classList.contains(allItems[0]), + "Focused item should not change if left arrow is pressed" + ) + sendKey("LEFT"); + + await waitForElementFocus("." + allItems[0]); + ok( + getFocusedMenuItem().classList.contains(allItems[0]), + "Focused item should not change if right arrow is pressed" + ) + sendKey("RIGHT"); + + await waitForElementFocus("." + allItems[0]); + ok( + getFocusedMenuItem().classList.contains(allItems[0]), + "Last item should cycle back to first item" + ); + + sendKey("UP"); + + let reversedItems = allItems.reverse(); + for (let item of reversedItems) { + await waitForElementFocus("." + item); + ok( + getFocusedMenuItem().classList.contains(item), + `.${item} should be selected after up key is pressed` + ); + sendKey("UP"); + } +}); +</script> + +</body> +</html> |