/* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ EXPECTED_BREACH = { AddedDate: "2018-12-20T23:56:26Z", BreachDate: "2018-12-16", Domain: "breached.example.com", Name: "Breached", PwnCount: 1643100, DataClasses: ["Email addresses", "Usernames", "Passwords", "IP addresses"], _status: "synced", id: "047940fe-d2fd-4314-b636-b4a952ee0043", last_modified: "1541615610052", schema: "1541615609018", }; let tabInSecondWindow; add_setup(async function () { TEST_LOGIN1 = await addLogin(TEST_LOGIN1); TEST_LOGIN2 = await addLogin(TEST_LOGIN2); TEST_LOGIN3 = await addLogin(TEST_LOGIN3); let breaches = await LoginBreaches.getPotentialBreachesByLoginGUID([ TEST_LOGIN3, ]); Assert.ok(breaches.size, "TEST_LOGIN3 should be marked as breached"); // Remove the breached login so the 'alerts' option // is hidden when opening about:logins. Services.logins.removeLogin(TEST_LOGIN3); await BrowserTestUtils.openNewForegroundTab({ gBrowser, url: "about:logins", }); let newWin = await BrowserTestUtils.openNewBrowserWindow(); tabInSecondWindow = await BrowserTestUtils.openNewForegroundTab({ gBrowser: newWin.gBrowser, url: "about:logins", }); registerCleanupFunction(async () => { BrowserTestUtils.removeTab(gBrowser.selectedTab); Services.logins.removeAllUserFacingLogins(); await BrowserTestUtils.closeWindow(newWin); }); }); add_task(async function test_new_login_marked_vulnerable_in_both_windows() { const ORIGIN_FOR_NEW_VULNERABLE_LOGIN = "https://vulnerable"; await SpecialPowers.spawn(gBrowser.selectedBrowser, [], async () => { let loginList = Cu.waiveXrays(content.document.querySelector("login-list")); Assert.ok( loginList.shadowRoot.querySelector("#login-sort").namedItem("alerts") .hidden, "The 'alerts' option should be hidden before adding a vulnerable login to the list" ); }); await SpecialPowers.spawn( tabInSecondWindow.linkedBrowser, [[TEST_LOGIN3.password, ORIGIN_FOR_NEW_VULNERABLE_LOGIN]], async ([passwordOfBreachedAccount, originForNewVulnerableLogin]) => { let loginList = content.document.querySelector("login-list"); await ContentTaskUtils.waitForCondition( () => loginList.shadowRoot.querySelectorAll(".login-list-item[data-guid]") .length == 2, "waiting for all two initials logins to get added to login-list" ); let loginSort = loginList.shadowRoot.querySelector("#login-sort"); Assert.ok( loginSort.namedItem("alerts").hidden, "The 'alerts' option should be hidden when there are no breached or vulnerable logins in the list" ); let createButton = loginList.shadowRoot.querySelector( ".create-login-button" ); createButton.click(); let loginItem = content.document.querySelector("login-item"); await ContentTaskUtils.waitForCondition( () => loginItem.dataset.isNewLogin, "waiting for create login form to be visible" ); let originInput = loginItem.shadowRoot.querySelector( "input[name='origin']" ); originInput.value = originForNewVulnerableLogin; let passwordInput = loginItem.shadowRoot.querySelector( "input[name='password']" ); passwordInput.value = passwordOfBreachedAccount; let saveButton = loginItem.shadowRoot.querySelector( ".save-changes-button" ); saveButton.click(); await ContentTaskUtils.waitForCondition( () => loginList.shadowRoot.querySelectorAll(".login-list-item[data-guid]") .length == 3, "waiting for new login to get added to login-list" ); let vulnerableLoginGuid = Cu.waiveXrays(loginItem)._login.guid; let vulnerableListItem = loginList.shadowRoot.querySelector( `.login-list-item[data-guid="${vulnerableLoginGuid}"]` ); Assert.ok( vulnerableListItem.classList.contains("vulnerable"), "vulnerable login list item should be marked as such" ); Assert.ok( !loginItem.shadowRoot.querySelector(".vulnerable-alert").hidden, "vulnerable alert on login-item should be visible" ); Assert.ok( !loginSort.namedItem("alerts").hidden, "The 'alerts' option should be visible after adding a vulnerable login to the list" ); } ); console.log("xxxxxxx ---- 0"); tabInSecondWindow.linkedBrowser.reload(); await BrowserTestUtils.browserLoaded( tabInSecondWindow.linkedBrowser, false, url => url.includes("about:logins") ); console.log("xxxxxxx ---- 1"); await SpecialPowers.spawn(tabInSecondWindow.linkedBrowser, [], async () => { let loginList = content.document.querySelector("login-list"); let loginSort = loginList.shadowRoot.querySelector("#login-sort"); await ContentTaskUtils.waitForCondition( () => loginSort.value == "alerts", "waiting for sort to get updated to 'alerts'" ); Assert.equal( loginSort.value, "alerts", "The login list should be sorted by Alerts" ); let loginListItems = loginList.shadowRoot.querySelectorAll( ".login-list-item[data-guid]" ); for (let i = 1; i < loginListItems.length; i++) { if (loginListItems[i].matches(".vulnerable, .breached")) { Assert.ok( loginListItems[i - 1].matches(".vulnerable, .breached"), `The previous login-list-item must be vulnerable or breached if the current one is (second window, i=${i})` ); } } }); console.log("xxxxxxx ---- 2"); await SpecialPowers.spawn( gBrowser.selectedBrowser, [ORIGIN_FOR_NEW_VULNERABLE_LOGIN], async originForNewVulnerableLogin => { let loginList = Cu.waiveXrays( content.document.querySelector("login-list") ); let vulnerableListItem; await ContentTaskUtils.waitForCondition(() => { let entry = Object.entries(loginList._logins).find( ([guid, { login, listItem }]) => login.origin == originForNewVulnerableLogin ); vulnerableListItem = entry[1].listItem; return !!entry; }, "waiting for vulnerable list item to get added to login-list"); Assert.ok( vulnerableListItem.classList.contains("vulnerable"), "vulnerable login list item should be marked as such" ); Assert.ok( !loginList.shadowRoot.querySelector("#login-sort").namedItem("alerts") .hidden, "The 'alerts' option should be visible after adding a vulnerable login to the list" ); } ); gBrowser.selectedBrowser.reload(); await BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser, false, url => url.includes("about:logins") ); await SpecialPowers.spawn(gBrowser.selectedBrowser, [], async () => { let loginList = Cu.waiveXrays(content.document.querySelector("login-list")); await ContentTaskUtils.waitForCondition( () => loginList.shadowRoot.querySelector("#login-sort").value == "alerts", "waiting for sort to get updated to 'alerts'" ); let loginListItems = loginList.shadowRoot.querySelectorAll( ".login-list-item[data-guid]" ); for (let i = 1; i < loginListItems.length; i++) { if (loginListItems[i].matches(".vulnerable, .breached")) { Assert.ok( loginListItems[i - 1].matches(".vulnerable, .breached"), `The previous login-list-item must be vulnerable or breached if the current one is (first window, i=${i})` ); } } }); });