summaryrefslogtreecommitdiffstats
path: root/comm/mail/components/unifiedtoolbar/test/browser/browser_searchBar.js
diff options
context:
space:
mode:
Diffstat (limited to 'comm/mail/components/unifiedtoolbar/test/browser/browser_searchBar.js')
-rw-r--r--comm/mail/components/unifiedtoolbar/test/browser/browser_searchBar.js263
1 files changed, 263 insertions, 0 deletions
diff --git a/comm/mail/components/unifiedtoolbar/test/browser/browser_searchBar.js b/comm/mail/components/unifiedtoolbar/test/browser/browser_searchBar.js
new file mode 100644
index 0000000000..b88c16f684
--- /dev/null
+++ b/comm/mail/components/unifiedtoolbar/test/browser/browser_searchBar.js
@@ -0,0 +1,263 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, you can obtain one at http://mozilla.org/MPL/2.0/. */
+
+let tabmail = document.getElementById("tabmail");
+registerCleanupFunction(() => {
+ tabmail.closeOtherTabs(tabmail.tabInfo[0]);
+});
+let browser;
+let searchBar;
+
+const waitForRender = () => {
+ return new Promise(resolve => {
+ window.requestAnimationFrame(resolve);
+ });
+};
+
+/* These are shadow-root safe variants of the methods in BrowserTestUtils. */
+
+/**
+ * Checks if a DOM element is hidden.
+ *
+ * @param {Element} element
+ * The element which is to be checked.
+ *
+ * @return {boolean}
+ */
+function is_hidden(element) {
+ var style = element.ownerGlobal.getComputedStyle(element);
+ if (style.display == "none") {
+ return true;
+ }
+ if (style.visibility != "visible") {
+ return true;
+ }
+ if (style.display == "-moz-popup") {
+ return ["hiding", "closed"].includes(element.state);
+ }
+
+ // Hiding a parent element will hide all its children
+ if (element.parentNode != element.ownerDocument && element.parentElement) {
+ return is_hidden(element.parentElement);
+ }
+
+ return false;
+}
+
+/**
+ * Checks if a DOM element is visible.
+ *
+ * @param {Element} element
+ * The element which is to be checked.
+ *
+ * @return {boolean}
+ */
+function is_visible(element) {
+ var style = element.ownerGlobal.getComputedStyle(element);
+ if (style.display == "none") {
+ return false;
+ }
+ if (style.visibility != "visible") {
+ return false;
+ }
+ if (style.display == "-moz-popup" && element.state != "open") {
+ return false;
+ }
+
+ // Hiding a parent element will hide all its children
+ if (element.parentNode != element.ownerDocument && element.parentElement) {
+ return is_visible(element.parentElement);
+ }
+
+ return true;
+}
+
+add_setup(async function () {
+ let tab = tabmail.openTab("contentTab", {
+ url: "chrome://mochitests/content/browser/comm/mail/components/unifiedtoolbar/test/browser/files/searchBar.xhtml",
+ });
+
+ await BrowserTestUtils.browserLoaded(tab.browser);
+ tab.browser.focus();
+ browser = tab.browser;
+ searchBar = tab.browser.contentWindow.document.querySelector("search-bar");
+});
+
+add_task(async function test_initialState() {
+ const input = searchBar.shadowRoot.querySelector("input");
+ is(
+ input.getAttribute("aria-label"),
+ searchBar.getAttribute("label"),
+ "Label forwarded to aria-label on input"
+ );
+});
+
+add_task(async function test_labelUpdate() {
+ const input = searchBar.shadowRoot.querySelector("input");
+ searchBar.setAttribute("label", "foo");
+ await waitForRender();
+ is(
+ input.getAttribute("aria-label"),
+ "foo",
+ "Updated label applied to content"
+ );
+});
+
+add_task(async function test_focus() {
+ const input = searchBar.shadowRoot.querySelector("input");
+ searchBar.focus();
+ is(
+ searchBar.shadowRoot.activeElement,
+ input,
+ "Input is focused when search bar is focused"
+ );
+});
+
+add_task(async function test_autocompleteEvent() {
+ const typeAndWaitForAutocomplete = async key => {
+ const eventPromise = BrowserTestUtils.waitForEvent(
+ searchBar,
+ "autocomplete"
+ );
+ await BrowserTestUtils.synthesizeKey(key, {}, browser);
+ return eventPromise;
+ };
+ searchBar.focus();
+ let event = await typeAndWaitForAutocomplete("T");
+ is(event.detail, "T", "Autocomplete for T");
+
+ event = await typeAndWaitForAutocomplete("e");
+ is(event.detail, "Te", "Autocomplete for e");
+
+ event = await typeAndWaitForAutocomplete("KEY_Backspace");
+ is(event.detail, "T", "Autocomplete for backspace");
+
+ await BrowserTestUtils.synthesizeKey("KEY_Backspace", {}, browser);
+});
+
+add_task(async function test_searchEventFromEnter() {
+ const input = searchBar.shadowRoot.querySelector("input");
+ input.value = "Lorem ipsum";
+ searchBar.focus();
+
+ const eventPromise = BrowserTestUtils.waitForEvent(searchBar, "search");
+ await BrowserTestUtils.synthesizeKey("KEY_Enter", {}, browser);
+ const event = await eventPromise;
+
+ is(event.detail, "Lorem ipsum", "Event contains search query");
+ await waitForRender();
+ is(input.value, "", "Input was cleared");
+});
+
+add_task(async function test_searchEventFromButton() {
+ const input = searchBar.shadowRoot.querySelector("input");
+ input.value = "Lorem ipsum";
+
+ const eventPromise = BrowserTestUtils.waitForEvent(searchBar, "search");
+ searchBar.shadowRoot.querySelector("button").click();
+ const event = await eventPromise;
+
+ is(event.detail, "Lorem ipsum", "Event contains search query");
+ await waitForRender();
+ is(input.value, "", "Input was cleared");
+});
+
+add_task(async function test_searchEventPreventDefault() {
+ const input = searchBar.shadowRoot.querySelector("input");
+ input.value = "Lorem ipsum";
+
+ searchBar.addEventListener(
+ "search",
+ event => {
+ event.preventDefault();
+ },
+ {
+ once: true,
+ passive: false,
+ }
+ );
+
+ const eventPromise = BrowserTestUtils.waitForEvent(searchBar, "search");
+ searchBar.shadowRoot.querySelector("button").click();
+ await eventPromise;
+ await waitForRender();
+
+ is(input.value, "Lorem ipsum");
+
+ input.value = "";
+});
+
+add_task(async function test_placeholderVisibility() {
+ const placeholder = searchBar.shadowRoot.querySelector("div");
+ const input = searchBar.shadowRoot.querySelector("input");
+
+ input.value = "";
+ await waitForRender();
+ ok(is_visible(placeholder), "Placeholder is visible initially");
+
+ input.value = "some input";
+ await waitForRender();
+ ok(is_hidden(placeholder), "Placeholder is hidden after text is entered");
+
+ input.value = "";
+ await waitForRender();
+ ok(
+ is_visible(placeholder),
+ "Placeholder is visible again after input is cleared"
+ );
+});
+
+add_task(async function test_placeholderFallbackToLabel() {
+ const placeholder = searchBar.querySelector("span");
+ placeholder.remove();
+
+ const shadowedPlaceholder = searchBar.shadowRoot.querySelector("div");
+ const label = searchBar.getAttribute("label");
+
+ is(
+ shadowedPlaceholder.textContent,
+ label,
+ "Falls back to label if no placeholder slot contents provided"
+ );
+
+ searchBar.setAttribute("label", "Foo bar");
+ is(
+ shadowedPlaceholder.textContent,
+ "Foo bar",
+ "Placeholder contents get updated with label attribute"
+ );
+
+ searchBar.prepend(placeholder);
+ searchBar.setAttribute("label", label);
+});
+
+add_task(async function test_reset() {
+ const input = searchBar.shadowRoot.querySelector("input");
+ const placeholder = searchBar.shadowRoot.querySelector("div");
+ input.value = "Lorem ipsum";
+
+ searchBar.reset();
+
+ is(input.value, "", "Input empty after reset");
+ await waitForRender();
+ ok(is_visible(placeholder), "Placeholder visible");
+});
+
+add_task(async function test_disabled() {
+ const input = searchBar.shadowRoot.querySelector("input");
+ const button = searchBar.shadowRoot.querySelector("button");
+
+ ok(!input.disabled, "Input enabled");
+ ok(!button.disabled, "Button enabled");
+
+ searchBar.setAttribute("disabled", true);
+
+ ok(input.disabled, "Disabled propagated to input");
+ ok(button.disabled, "Disabled propagated to button");
+
+ searchBar.removeAttribute("disabled");
+
+ ok(!input.disabled, "Input enabled again");
+ ok(!button.disabled, "Button enabled again");
+});