diff options
Diffstat (limited to 'toolkit/components/passwordmgr/test/browser/browser_autocomplete_primary_password.js')
-rw-r--r-- | toolkit/components/passwordmgr/test/browser/browser_autocomplete_primary_password.js | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/toolkit/components/passwordmgr/test/browser/browser_autocomplete_primary_password.js b/toolkit/components/passwordmgr/test/browser/browser_autocomplete_primary_password.js new file mode 100644 index 0000000000..c3152740cd --- /dev/null +++ b/toolkit/components/passwordmgr/test/browser/browser_autocomplete_primary_password.js @@ -0,0 +1,121 @@ +/* eslint-disable mozilla/no-arbitrary-setTimeout */ +const HOST = "https://example.com"; +const URL = + HOST + "/browser/toolkit/components/passwordmgr/test/browser/form_basic.html"; +const TIMEOUT_PREF = "signon.masterPasswordReprompt.timeout_ms"; + +const BRAND_BUNDLE = Services.strings.createBundle( + "chrome://branding/locale/brand.properties" +); +const BRAND_FULL_NAME = BRAND_BUNDLE.GetStringFromName("brandFullName"); + +// Waits for the primary password prompt and cancels it when close() is called on the return value. +async function waitForDialog() { + let [subject] = await TestUtils.topicObserved("common-dialog-loaded"); + let dialog = subject.Dialog; + let expected = "Password Required - " + BRAND_FULL_NAME; + Assert.equal(dialog.args.title, expected, "Check common dialog title"); + return { + async close(win = window) { + dialog.ui.button1.click(); + return BrowserTestUtils.waitForEvent(win, "DOMModalDialogClosed"); + }, + }; +} + +add_setup(async function () { + let login = LoginTestUtils.testData.formLogin({ + origin: "https://example.com", + formActionOrigin: "https://example.com", + username: "username", + password: "password", + }); + await Services.logins.addLoginAsync(login); + LoginTestUtils.primaryPassword.enable(); + + registerCleanupFunction(function () { + LoginTestUtils.primaryPassword.disable(); + }); + + // Set primary password prompt timeout to 3s. + // If this test goes intermittent, you likely have to increase this value. + await SpecialPowers.pushPrefEnv({ set: [[TIMEOUT_PREF, 3000]] }); +}); + +// Test that autocomplete does not trigger a primary password prompt +// for a certain time after it was cancelled. +add_task(async function test_mpAutocompleteTimeout() { + // Wait for initial primary password dialog after opening the tab. + let dialogShown = waitForDialog(); + + await BrowserTestUtils.withNewTab(URL, async function (browser) { + (await dialogShown).close(); + + await SpecialPowers.spawn(browser, [], async function () { + // Focus the password field to trigger autocompletion. + content.document.getElementById("form-basic-password").focus(); + }); + + // Wait 4s, dialog should not have been shown + // (otherwise the code below will not work). + await new Promise(c => setTimeout(c, 4000)); + + dialogShown = waitForDialog(); + await SpecialPowers.spawn(browser, [], async function () { + // Re-focus the password field to trigger autocompletion. + content.document.getElementById("form-basic-username").focus(); + content.document.getElementById("form-basic-password").focus(); + }); + (await dialogShown).close(); + closePopup(document.getElementById("PopupAutoComplete")); + }); + + // Wait 4s for the timer to pass again and not interfere with the next test. + await new Promise(c => setTimeout(c, 4000)); +}); + +// Test that autocomplete does not trigger a primary password prompt +// if one is already showing. +add_task(async function test_mpAutocompleteUIBusy() { + // Wait for initial primary password dialog after adding the login. + let dialogShown = waitForDialog(); + + let win = await BrowserTestUtils.openNewBrowserWindow(); + + Services.tm.dispatchToMainThread(async () => { + try { + // Trigger a MP prompt in the new window by saving a login + await Services.logins.addLoginAsync(LoginTestUtils.testData.formLogin()); + } catch (e) { + // Handle throwing from MP cancellation + } + }); + let { close } = await dialogShown; + + let windowGlobal = + gBrowser.selectedBrowser.browsingContext.currentWindowGlobal; + let loginManagerParent = windowGlobal.getActor("LoginManager"); + let origin = "https://www.example.com"; + let data = { + actionOrigin: "", + searchString: "", + previousResult: null, + hasBeenTypePassword: true, + isSecure: false, + isProbablyANewPasswordField: true, + }; + + function dialogObserver(subject, topic, data) { + Assert.ok(false, "A second dialog shouldn't have been shown"); + Services.obs.removeObserver(dialogObserver, topic); + } + Services.obs.addObserver(dialogObserver, "common-dialog-loaded"); + + let results = await loginManagerParent.doAutocompleteSearch(origin, data); + Assert.equal(results.logins.length, 0, "No results since uiBusy is true"); + await close(win); + + await BrowserTestUtils.closeWindow(win); + + Services.obs.removeObserver(dialogObserver, "common-dialog-loaded"); +}); |