mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-21 09:15:35 +00:00
Bug 1571463 - Fix 'Create new login' item visibility in about:logins. r=jaws
Differential Revision: https://phabricator.services.mozilla.com/D41087 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
9cd23a9635
commit
724b9427aa
@ -43,8 +43,10 @@
|
||||
display: contents;
|
||||
}
|
||||
|
||||
:host(.no-logins) ol,
|
||||
:host(:not(.no-logins)) .intro {
|
||||
:host(.no-logins:not(.create-login-selected)) ol,
|
||||
:host(:not(.no-logins)) .intro,
|
||||
:host(.create-login-selected) .intro,
|
||||
:host(:not(.create-login-selected)) #new-login-list-item {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
@ -102,7 +102,10 @@ export default class LoginList extends HTMLElement {
|
||||
|
||||
listItem.hidden = !visibleLoginGuids.has(listItem.dataset.guid);
|
||||
}
|
||||
this._blankLoginListItem.hidden = this._selectedGuid != null;
|
||||
this.classList.toggle(
|
||||
"create-login-selected",
|
||||
this._selectedGuid == null && Object.keys(this._logins).length > 0
|
||||
);
|
||||
|
||||
// Re-arrange the login-list-items according to their sort
|
||||
for (let i = this._loginGuidsSortedOrder.length - 1; i >= 0; i--) {
|
||||
@ -471,7 +474,7 @@ export default class LoginList extends HTMLElement {
|
||||
oldSelectedItem.classList.remove("selected");
|
||||
oldSelectedItem.removeAttribute("aria-selected");
|
||||
}
|
||||
this._blankLoginListItem.hidden = !!listItem.dataset.guid;
|
||||
this.classList.toggle("create-login-selected", !listItem.dataset.guid);
|
||||
listItem.classList.add("selected");
|
||||
listItem.setAttribute("aria-selected", "true");
|
||||
this._list.setAttribute("aria-activedescendant", listItem.id);
|
||||
|
@ -47,11 +47,23 @@ add_task(async function test_create_login() {
|
||||
);
|
||||
|
||||
await ContentTask.spawn(browser, originTuple, async aOriginTuple => {
|
||||
let createButton = content.document
|
||||
.querySelector("login-list")
|
||||
.shadowRoot.querySelector(".create-login-button");
|
||||
let loginList = Cu.waiveXrays(
|
||||
content.document.querySelector("login-list")
|
||||
);
|
||||
let createButton = loginList.shadowRoot.querySelector(
|
||||
".create-login-button"
|
||||
);
|
||||
is(
|
||||
content.getComputedStyle(loginList._blankLoginListItem).display,
|
||||
"none",
|
||||
"the blank login list item should be hidden initially"
|
||||
);
|
||||
createButton.click();
|
||||
await Promise.resolve();
|
||||
isnot(
|
||||
content.getComputedStyle(loginList._blankLoginListItem).display,
|
||||
"none",
|
||||
"the blank login list item should be visible after clicking on the create button"
|
||||
);
|
||||
|
||||
let loginItem = Cu.waiveXrays(
|
||||
content.document.querySelector("login-item")
|
||||
@ -101,6 +113,11 @@ add_task(async function test_create_login() {
|
||||
!loginList.classList.contains("no-logins"),
|
||||
"login-list should no longer be in no logins view"
|
||||
);
|
||||
is(
|
||||
content.getComputedStyle(loginList._blankLoginListItem).display,
|
||||
"none",
|
||||
"the blank login list item should be hidden after adding new login"
|
||||
);
|
||||
let loginGuid = await ContentTaskUtils.waitForCondition(() => {
|
||||
return loginList._loginGuidsSortedOrder.find(
|
||||
guid => loginList._logins[guid].login.origin == aOriginTuple[1]
|
||||
@ -191,8 +208,9 @@ add_task(async function test_cancel_create_login() {
|
||||
loginList._selectedGuid,
|
||||
"there should be a selected guid before create mode"
|
||||
);
|
||||
ok(
|
||||
loginList._blankLoginListItem.hidden,
|
||||
is(
|
||||
content.getComputedStyle(loginList._blankLoginListItem).display,
|
||||
"none",
|
||||
"the blank login list item should be hidden before create mode"
|
||||
);
|
||||
|
||||
@ -205,8 +223,9 @@ add_task(async function test_cancel_create_login() {
|
||||
!loginList._selectedGuid,
|
||||
"there should be no selected guid when in create mode"
|
||||
);
|
||||
ok(
|
||||
!loginList._blankLoginListItem.hidden,
|
||||
isnot(
|
||||
content.getComputedStyle(loginList._blankLoginListItem).display,
|
||||
"none",
|
||||
"the blank login list item should be visible in create mode"
|
||||
);
|
||||
|
||||
@ -218,8 +237,9 @@ add_task(async function test_cancel_create_login() {
|
||||
loginList._selectedGuid,
|
||||
"there should be a selected guid after canceling create mode"
|
||||
);
|
||||
ok(
|
||||
loginList._blankLoginListItem.hidden,
|
||||
is(
|
||||
content.getComputedStyle(loginList._blankLoginListItem).display,
|
||||
"none",
|
||||
"the blank login list item should be hidden after canceling create mode"
|
||||
);
|
||||
});
|
||||
|
@ -74,7 +74,7 @@ add_task(async function test_query_parameter_filter() {
|
||||
".login-list-item[hidden]"
|
||||
);
|
||||
let visibleLoginListItems = loginList.shadowRoot.querySelectorAll(
|
||||
".login-list-item:not([hidden])"
|
||||
".login-list-item:not(#new-login-list-item):not([hidden])"
|
||||
);
|
||||
is(visibleLoginListItems.length, 1, "The one login should be visible");
|
||||
is(
|
||||
@ -82,9 +82,9 @@ add_task(async function test_query_parameter_filter() {
|
||||
logins[0].guid,
|
||||
"TEST_LOGIN1 should be visible"
|
||||
);
|
||||
is(hiddenLoginListItems.length, 2, "One login should be hidden");
|
||||
is(hiddenLoginListItems.length, 1, "One login should be hidden");
|
||||
is(
|
||||
hiddenLoginListItems[1].dataset.guid,
|
||||
hiddenLoginListItems[0].dataset.guid,
|
||||
logins[1].guid,
|
||||
"TEST_LOGIN2 should be hidden"
|
||||
);
|
||||
|
@ -111,21 +111,21 @@ add_task(async function test_keyboard_navigation() {
|
||||
|
||||
for (let [keyFwd, keyRev] of [["LEFT", "RIGHT"], ["DOWN", "UP"]]) {
|
||||
sendKey(keyFwd);
|
||||
await SimpleTest.promiseWaitForCondition(() => ol.getAttribute("aria-activedescendant") == ol.querySelectorAll(".login-list-item:not([hidden])")[1].id,
|
||||
await SimpleTest.promiseWaitForCondition(() => ol.getAttribute("aria-activedescendant") == ol.querySelectorAll(".login-list-item:not(#new-login-list-item):not([hidden])")[1].id,
|
||||
`waiting for second item in list to get focused (${keyFwd})`);
|
||||
ok(ol.querySelectorAll(".login-list-item:not([hidden])")[1].classList.contains("keyboard-selected"), `second item should be marked as keyboard-selected (${keyFwd})`);
|
||||
ok(ol.querySelectorAll(".login-list-item:not(#new-login-list-item):not([hidden])")[1].classList.contains("keyboard-selected"), `second item should be marked as keyboard-selected (${keyFwd})`);
|
||||
|
||||
sendKey(keyRev);
|
||||
await SimpleTest.promiseWaitForCondition(() => ol.getAttribute("aria-activedescendant") == ol.querySelectorAll(".login-list-item:not([hidden])")[0].id,
|
||||
await SimpleTest.promiseWaitForCondition(() => ol.getAttribute("aria-activedescendant") == ol.querySelectorAll(".login-list-item:not(#new-login-list-item):not([hidden])")[0].id,
|
||||
`waiting for first item in list to get focused (${keyRev})`);
|
||||
ok(ol.querySelectorAll(".login-list-item:not([hidden])")[0].classList.contains("keyboard-selected"), `first item should be marked as keyboard-selected (${keyRev})`);
|
||||
ok(ol.querySelectorAll(".login-list-item:not(#new-login-list-item):not([hidden])")[0].classList.contains("keyboard-selected"), `first item should be marked as keyboard-selected (${keyRev})`);
|
||||
}
|
||||
|
||||
sendKey("DOWN");
|
||||
await SimpleTest.promiseWaitForCondition(() => ol.getAttribute("aria-activedescendant") == ol.querySelectorAll(".login-list-item:not([hidden])")[1].id,
|
||||
await SimpleTest.promiseWaitForCondition(() => ol.getAttribute("aria-activedescendant") == ol.querySelectorAll(".login-list-item:not(#new-login-list-item):not([hidden])")[1].id,
|
||||
`waiting for second item in list to get focused (DOWN)`);
|
||||
ok(ol.querySelectorAll(".login-list-item:not([hidden])")[1].classList.contains("keyboard-selected"), `second item should be marked as keyboard-selected (DOWN)`);
|
||||
let selectedGuid = ol.querySelectorAll(".login-list-item:not([hidden])")[1].dataset.guid;
|
||||
ok(ol.querySelectorAll(".login-list-item:not(#new-login-list-item):not([hidden])")[1].classList.contains("keyboard-selected"), `second item should be marked as keyboard-selected (DOWN)`);
|
||||
let selectedGuid = ol.querySelectorAll(".login-list-item:not(#new-login-list-item):not([hidden])")[1].dataset.guid;
|
||||
|
||||
let loginSelectedEvent = null;
|
||||
gLoginList.addEventListener("AboutLoginsLoginSelected", event => loginSelectedEvent = event, {once: true});
|
||||
@ -142,7 +142,7 @@ add_task(async function test_empty_login_username_in_list() {
|
||||
}));
|
||||
|
||||
gLoginList.setLogins([TEST_LOGIN_3]);
|
||||
let loginListItems = gLoginList.shadowRoot.querySelectorAll(".login-list-item:not([hidden])");
|
||||
let loginListItems = gLoginList.shadowRoot.querySelectorAll(".login-list-item:not(#new-login-list-item):not([hidden])");
|
||||
is(loginListItems.length, 1, "The one stored login should be displayed");
|
||||
is(loginListItems[0].dataset.guid, TEST_LOGIN_3.guid, "login-list-item should have correct guid attribute");
|
||||
let loginUsername = loginListItems[0].querySelector(".username");
|
||||
@ -151,7 +151,7 @@ add_task(async function test_empty_login_username_in_list() {
|
||||
|
||||
add_task(async function test_populated_list() {
|
||||
gLoginList.setLogins([TEST_LOGIN_1, TEST_LOGIN_2]);
|
||||
let loginListItems = gLoginList.shadowRoot.querySelectorAll(".login-list-item:not([hidden])");
|
||||
let loginListItems = gLoginList.shadowRoot.querySelectorAll(".login-list-item:not(#new-login-list-item):not([hidden])");
|
||||
is(loginListItems.length, 2, "The two stored logins should be displayed");
|
||||
is(loginListItems[0].getAttribute("role"), "option", "Each login-list-item should have role='option'");
|
||||
is(loginListItems[0].dataset.guid, TEST_LOGIN_1.guid, "login-list-item should have correct guid attribute");
|
||||
@ -162,7 +162,7 @@ add_task(async function test_populated_list() {
|
||||
ok(loginListItems[0].classList.contains("selected"), "The first item should be selected by default");
|
||||
ok(!loginListItems[1].classList.contains("selected"), "The second item should not be selected by default");
|
||||
loginListItems[0].click();
|
||||
loginListItems = gLoginList.shadowRoot.querySelectorAll(".login-list-item:not([hidden])");
|
||||
loginListItems = gLoginList.shadowRoot.querySelectorAll(".login-list-item:not(#new-login-list-item):not([hidden])");
|
||||
is(loginListItems.length, 2, "After selecting one, only the two stored logins should be displayed");
|
||||
ok(loginListItems[0].classList.contains("selected"), "The first item should be selected");
|
||||
ok(!loginListItems[1].classList.contains("selected"), "The second item should still not be selected");
|
||||
@ -170,13 +170,13 @@ add_task(async function test_populated_list() {
|
||||
|
||||
add_task(async function test_breach_indicator() {
|
||||
gLoginList.updateBreaches(TEST_BREACHES_MAP);
|
||||
let loginListItems = gLoginList.shadowRoot.querySelectorAll(".login-list-item:not([hidden])");
|
||||
let loginListItems = gLoginList.shadowRoot.querySelectorAll(".login-list-item:not(#new-login-list-item):not([hidden])");
|
||||
ok(loginListItems[0].classList.contains("breached"), "The first login should have the .breached class.");
|
||||
ok(!loginListItems[1].classList.contains("breached"), "The second login should not have the .breached class");
|
||||
});
|
||||
|
||||
add_task(async function test_filtered_list() {
|
||||
is(gLoginList.shadowRoot.querySelectorAll(".login-list-item:not([hidden])").length, 2, "Both logins should be visible");
|
||||
is(gLoginList.shadowRoot.querySelectorAll(".login-list-item:not(#new-login-list-item):not([hidden])").length, 2, "Both logins should be visible");
|
||||
let countSpan = gLoginList.shadowRoot.querySelector(".count");
|
||||
is(JSON.parse(countSpan.getAttribute("data-l10n-args")).count, 2, "Count should match full list length");
|
||||
window.dispatchEvent(new CustomEvent("AboutLoginsFilterLogins", {
|
||||
@ -240,12 +240,12 @@ add_task(async function test_login_modified() {
|
||||
add_task(async function test_login_added() {
|
||||
info("selected sort: " + gLoginList.shadowRoot.getElementById("login-sort").selectedIndex);
|
||||
|
||||
let loginListItems = gLoginList.shadowRoot.querySelectorAll(".login-list-item:not([hidden])");
|
||||
let loginListItems = gLoginList.shadowRoot.querySelectorAll(".login-list-item:not(#new-login-list-item):not([hidden])");
|
||||
is(loginListItems.length, 2, "Should have two logins at start of test");
|
||||
let newLogin = Object.assign({}, TEST_LOGIN_1, {title: "example2.example.com", guid: "111222"});
|
||||
gLoginList.loginAdded(newLogin);
|
||||
await asyncElementRendered();
|
||||
loginListItems = gLoginList.shadowRoot.querySelectorAll(".login-list-item:not([hidden])");
|
||||
loginListItems = gLoginList.shadowRoot.querySelectorAll(".login-list-item:not(#new-login-list-item):not([hidden])");
|
||||
is(loginListItems.length, 3, "New login should be added to the list");
|
||||
is(loginListItems[0].dataset.guid, TEST_LOGIN_1.guid, "login-list-item1 should have correct guid attribute");
|
||||
is(loginListItems[1].dataset.guid, TEST_LOGIN_2.guid, "login-list-item2 should have correct guid attribute");
|
||||
@ -259,7 +259,7 @@ add_task(async function test_login_added() {
|
||||
add_task(async function test_login_removed() {
|
||||
gLoginList.loginRemoved({guid: "111222"});
|
||||
await asyncElementRendered();
|
||||
let loginListItems = gLoginList.shadowRoot.querySelectorAll(".login-list-item:not([hidden])");
|
||||
let loginListItems = gLoginList.shadowRoot.querySelectorAll(".login-list-item:not(#new-login-list-item):not([hidden])");
|
||||
is(loginListItems.length, 2, "New login should be removed from the list");
|
||||
is(loginListItems[0].dataset.guid, TEST_LOGIN_1.guid, "login-list-item1 should have correct guid attribute");
|
||||
is(loginListItems[1].dataset.guid, TEST_LOGIN_2.guid, "login-list-item2 should have correct guid attribute");
|
||||
@ -320,7 +320,7 @@ add_task(async function test_sorted_list() {
|
||||
let loginSort = gLoginList.shadowRoot.getElementById("login-sort");
|
||||
loginSort.selectedIndex = 1;
|
||||
dispatchChangeEvent(loginSort);
|
||||
let loginListItems = gLoginList.shadowRoot.querySelectorAll(".login-list-item:not([hidden])");
|
||||
let loginListItems = gLoginList.shadowRoot.querySelectorAll(".login-list-item:not(#new-login-list-item):not([hidden])");
|
||||
is(loginListItems.length, 3, "The list should contain the three stored logins");
|
||||
let timeUsed1 = gLoginList._logins[loginListItems[0].dataset.guid].login.timeLastUsed;
|
||||
let timeUsed2 = gLoginList._logins[loginListItems[1].dataset.guid].login.timeLastUsed;
|
||||
@ -331,7 +331,7 @@ add_task(async function test_sorted_list() {
|
||||
// sort by title
|
||||
loginSort.selectedIndex = 0;
|
||||
dispatchChangeEvent(loginSort);
|
||||
loginListItems = gLoginList.shadowRoot.querySelectorAll(".login-list-item:not([hidden])");
|
||||
loginListItems = gLoginList.shadowRoot.querySelectorAll(".login-list-item:not(#new-login-list-item):not([hidden])");
|
||||
let title1 = gLoginList._logins[loginListItems[0].dataset.guid].login.title;
|
||||
let title2 = gLoginList._logins[loginListItems[1].dataset.guid].login.title;
|
||||
let title3 = gLoginList._logins[loginListItems[2].dataset.guid].login.title;
|
||||
@ -341,7 +341,7 @@ add_task(async function test_sorted_list() {
|
||||
// sort by last changed
|
||||
loginSort.selectedIndex = 2;
|
||||
dispatchChangeEvent(loginSort);
|
||||
loginListItems = gLoginList.shadowRoot.querySelectorAll(".login-list-item:not([hidden])");
|
||||
loginListItems = gLoginList.shadowRoot.querySelectorAll(".login-list-item:not(#new-login-list-item):not([hidden])");
|
||||
let pwChanged1 = gLoginList._logins[loginListItems[0].dataset.guid].login.timePasswordChanged;
|
||||
let pwChanged2 = gLoginList._logins[loginListItems[1].dataset.guid].login.timePasswordChanged;
|
||||
let pwChanged3 = gLoginList._logins[loginListItems[2].dataset.guid].login.timePasswordChanged;
|
||||
@ -352,7 +352,7 @@ add_task(async function test_sorted_list() {
|
||||
gLoginList.updateBreaches(TEST_BREACHES_MAP);
|
||||
loginSort.selectedIndex = 3;
|
||||
dispatchChangeEvent(loginSort);
|
||||
loginListItems = gLoginList.shadowRoot.querySelectorAll(".login-list-item:not([hidden])");
|
||||
loginListItems = gLoginList.shadowRoot.querySelectorAll(".login-list-item:not(#new-login-list-item):not([hidden])");
|
||||
is(loginListItems[0].classList.contains("breached"), true, "Breached login should be displayed at top of list");
|
||||
is(!loginListItems[1].classList.contains("breached"), true, "Non-breached login should be displayed below breached");
|
||||
|
||||
@ -360,7 +360,7 @@ add_task(async function test_sorted_list() {
|
||||
gLoginList.updateBreaches(new Map());
|
||||
loginSort.selectedIndex = 3;
|
||||
dispatchChangeEvent(loginSort);
|
||||
loginListItems = gLoginList.shadowRoot.querySelectorAll(".login-list-item:not([hidden])");
|
||||
loginListItems = gLoginList.shadowRoot.querySelectorAll(".login-list-item:not(#new-login-list-item):not([hidden])");
|
||||
title1 = gLoginList._logins[loginListItems[0].dataset.guid].login.title;
|
||||
title2 = gLoginList._logins[loginListItems[1].dataset.guid].login.title;
|
||||
is(title1.localeCompare(title2), -1, "Logins should be sorted alphabetically by hostname");
|
||||
|
Loading…
Reference in New Issue
Block a user