diff options
Diffstat (limited to 'browser/components/aboutlogins/tests/chrome/test_login_filter.html')
-rw-r--r-- | browser/components/aboutlogins/tests/chrome/test_login_filter.html | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/browser/components/aboutlogins/tests/chrome/test_login_filter.html b/browser/components/aboutlogins/tests/chrome/test_login_filter.html new file mode 100644 index 0000000000..00e0a96a51 --- /dev/null +++ b/browser/components/aboutlogins/tests/chrome/test_login_filter.html @@ -0,0 +1,178 @@ +<!DOCTYPE HTML> +<html> +<!-- +Test the login-filter component +--> +<head> + <meta charset="utf-8"> + <title>Test the login-filter 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/login-filter.mjs"></script> + <script type="module" src="chrome://browser/content/aboutlogins/components/login-list.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 login-filter component **/ + +let gLoginFilter; +let gLoginList; +add_setup(async () => { + let templateFrame = document.getElementById("templateFrame"); + let displayEl = document.getElementById("display"); + importDependencies(templateFrame, displayEl); + + gLoginFilter = document.createElement("login-filter"); + displayEl.appendChild(gLoginFilter); + + gLoginList = document.createElement("login-list"); + displayEl.appendChild(gLoginList); +}); + +add_task(async function test_empty_filter() { + ok(gLoginFilter, "loginFilter exists"); + is(gLoginFilter.shadowRoot.querySelector("input").value, "", "Initially empty"); +}); + +add_task(async function test_input_events() { + let filterEvent = null; + window.addEventListener("AboutLoginsFilterLogins", event => filterEvent = event); + let input = SpecialPowers.wrap(gLoginFilter.shadowRoot.querySelector("input")); + input.setUserInput("test"); + ok(filterEvent, "Filter event received"); + is(filterEvent.detail, "test", "Event includes input value"); +}); + +add_task(async function test_list_filtered() { + const LOGINS = [{ + guid: "123456789", + origin: "https://example.com", + username: "user1", + password: "pass1", + }, { + guid: "987654321", + origin: "https://example.com", + username: "user2", + password: "pass2", + }]; + gLoginList.setLogins(LOGINS); + + let tests = [ + ["", 2], + [LOGINS[0].username, 1], + [LOGINS[0].username + "-notfound", 0], + [LOGINS[0].username.substr(2, 3), 1], + ["", 2], + // The password is also used for search when MP is disabled. + [LOGINS[0].password, 1], + [LOGINS[0].password + "-notfound", 0], + [LOGINS[0].password.substr(2, 3), 1], + ["", 2], + [LOGINS[0].origin, 2], + [LOGINS[0].origin + "-notfound", 0], + [LOGINS[0].origin.substr(2, 3), 2], + ["", 2], + // The guid is not used for search. + [LOGINS[0].guid, 0], + [LOGINS[0].guid + "-notfound", 0], + [LOGINS[0].guid.substr(0, 2), 0], + ["", 2], + ]; + + let loginFilterInput = gLoginFilter.shadowRoot.querySelector("input"); + loginFilterInput.focus(); + + for (let i = 0; i < tests.length; i++) { + info("Testcase: " + i); + + let testObj = { + testCase: i, + query: tests[i][0], + resultExpectedCount: tests[i][1], + }; + + let filterLength = loginFilterInput.value.length; + while (filterLength-- > 0) { + sendKey("BACK_SPACE"); + } + sendString(testObj.query); + + await SimpleTest.promiseWaitForCondition(() => { + let countElement = gLoginList.shadowRoot.querySelector(".count"); + return countElement.hasAttribute("data-l10n-args") && + JSON.parse(countElement.getAttribute("data-l10n-args")).count == testObj.resultExpectedCount; + }, `Waiting for the search result count to update to ${testObj.resultExpectedCount} (tc#${testObj.testCase})`); + } +}); + + add_task(async function test_keys_in_filter() { + const LOGINS = [{ + guid: "123456789", + origin: "https://example.com", + username: "user1", + password: "pass1", + }, { + guid: "987654321", + origin: "https://example.com", + username: "user2", + password: "pass2", + }, { + guid: "333333333", + origin: "https://example.com", + username: "user3", + password: "pass3", + }]; + gLoginList.setLogins(LOGINS); + + const ol = gLoginList.shadowRoot.querySelector("ol"); + const loginFilterInput = gLoginFilter.shadowRoot.querySelector("input"); + loginFilterInput.focus(); + + // Up/down keys must select previous/next item in the list + function pressKeyAndExpectSelection(key, selectedIndex) { + sendKey(key); + ok(ol.querySelectorAll(".login-list-item[data-guid]:not([hidden])")[selectedIndex]?.classList?.contains("keyboard-selected"), + `item ${selectedIndex} should be marked as keyboard-selected`); + is(ol.querySelector(".selected").dataset.guid, LOGINS[selectedIndex].guid, `item ${selectedIndex} must be selected`); + } + + pressKeyAndExpectSelection("DOWN", 1); + pressKeyAndExpectSelection("DOWN", 2); + + // ENTER key in search box must click on selected item in the list + sendKey("RETURN"); + is(ol.querySelector(".selected").dataset.guid, LOGINS[2].guid, "item 2 must still be selected"); + + pressKeyAndExpectSelection("DOWN", 2); + pressKeyAndExpectSelection("UP", 1); + pressKeyAndExpectSelection("UP", 0); + pressKeyAndExpectSelection("UP", 0); + + // ESC must clear search box + async function expectItemCount(count) { + await SimpleTest.promiseWaitForCondition(() => + JSON.parse(gLoginList.shadowRoot.querySelector(".count").getAttribute("data-l10n-args"))?.count == count, + `Waiting for the search result count to update to ${count}`); + } + + sendString("unique string"); + await expectItemCount(0); + sendKey("Escape"); + ok(!loginFilterInput.value, "ESC must clear filter input"); + await expectItemCount(LOGINS.length); + }); +</script> + +</body> +</html> |