diff options
Diffstat (limited to 'toolkit/components/passwordmgr/test/mochitest/pwmgr_common_parent.js')
-rw-r--r-- | toolkit/components/passwordmgr/test/mochitest/pwmgr_common_parent.js | 249 |
1 files changed, 249 insertions, 0 deletions
diff --git a/toolkit/components/passwordmgr/test/mochitest/pwmgr_common_parent.js b/toolkit/components/passwordmgr/test/mochitest/pwmgr_common_parent.js new file mode 100644 index 0000000000..00173cf323 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/pwmgr_common_parent.js @@ -0,0 +1,249 @@ +/** + * Loaded as a frame script to do privileged things in mochitest-plain tests. + * See pwmgr_common.js for the content process companion. + */ + +/* eslint-env mozilla/chrome-script */ + +"use strict"; + +var { AppConstants } = ChromeUtils.importESModule( + "resource://gre/modules/AppConstants.sys.mjs" +); +var { LoginHelper } = ChromeUtils.importESModule( + "resource://gre/modules/LoginHelper.sys.mjs" +); +var { LoginManagerParent } = ChromeUtils.importESModule( + "resource://gre/modules/LoginManagerParent.sys.mjs" +); +const { LoginTestUtils } = ChromeUtils.importESModule( + "resource://testing-common/LoginTestUtils.sys.mjs" +); +if (LoginHelper.relatedRealmsEnabled) { + let rsPromise = + LoginTestUtils.remoteSettings.setupWebsitesWithSharedCredentials(); + async () => { + await rsPromise; + }; +} +if (LoginHelper.improvedPasswordRulesEnabled) { + let rsPromise = LoginTestUtils.remoteSettings.setupImprovedPasswordRules({ + rules: "", + }); + async () => { + await rsPromise; + }; +} + +/** + * Init with a common login + * If selfFilling is true or non-undefined, fires an event at the page so that + * the test can start checking filled-in values. Tests that check observer + * notifications might be confused by this. + */ +async function commonInit(selfFilling, testDependsOnDeprecatedLogin) { + var pwmgr = Services.logins; + assert.ok(pwmgr != null, "Access LoginManager"); + + // Check that initial state has no logins + var logins = pwmgr.getAllLogins(); + assert.equal(logins.length, 0, "Not expecting logins to be present"); + var disabledHosts = pwmgr.getAllDisabledHosts(); + if (disabledHosts.length) { + assert.ok(false, "Warning: wasn't expecting disabled hosts to be present."); + for (var host of disabledHosts) { + pwmgr.setLoginSavingEnabled(host, true); + } + } + + if (testDependsOnDeprecatedLogin) { + // Add a login that's used in multiple tests + var login = Cc["@mozilla.org/login-manager/loginInfo;1"].createInstance( + Ci.nsILoginInfo + ); + login.init( + "http://mochi.test:8888", + "http://mochi.test:8888", + null, + "testuser", + "testpass", + "uname", + "pword" + ); + await pwmgr.addLoginAsync(login); + } + + // Last sanity check + logins = pwmgr.getAllLogins(); + assert.equal( + logins.length, + testDependsOnDeprecatedLogin ? 1 : 0, + "Checking for successful init login" + ); + disabledHosts = pwmgr.getAllDisabledHosts(); + assert.equal(disabledHosts.length, 0, "Checking for no disabled hosts"); + + if (selfFilling) { + return; + } + + // Notify the content side that initialization is done and tests can start. + sendAsyncMessage("registerRunTests"); +} + +function dumpLogins() { + let logins = Services.logins.getAllLogins(); + assert.ok(true, "----- dumpLogins: have " + logins.length + " logins. -----"); + for (var i = 0; i < logins.length; i++) { + dumpLogin("login #" + i + " --- ", logins[i]); + } +} + +function dumpLogin(label, login) { + var loginText = ""; + loginText += "origin: "; + loginText += login.origin; + loginText += " / formActionOrigin: "; + loginText += login.formActionOrigin; + loginText += " / realm: "; + loginText += login.httpRealm; + loginText += " / user: "; + loginText += login.username; + loginText += " / pass: "; + loginText += login.password; + loginText += " / ufield: "; + loginText += login.usernameField; + loginText += " / pfield: "; + loginText += login.passwordField; + assert.ok(true, label + loginText); +} + +function onStorageChanged(subject, topic, data) { + sendAsyncMessage("storageChanged", { + topic, + data, + }); +} +Services.obs.addObserver(onStorageChanged, "passwordmgr-storage-changed"); + +function onPrompt(subject, topic, data) { + sendAsyncMessage("promptShown", { + topic, + data, + }); +} +Services.obs.addObserver(onPrompt, "passwordmgr-prompt-change"); +Services.obs.addObserver(onPrompt, "passwordmgr-prompt-save"); + +addMessageListener("cleanup", () => { + Services.obs.removeObserver(onStorageChanged, "passwordmgr-storage-changed"); + Services.obs.removeObserver(onPrompt, "passwordmgr-prompt-change"); + Services.obs.removeObserver(onPrompt, "passwordmgr-prompt-save"); + Services.logins.removeAllUserFacingLogins(); +}); + +// Begin message listeners + +addMessageListener( + "setupParent", + async ({ + selfFilling = false, + testDependsOnDeprecatedLogin = false, + } = {}) => { + await commonInit(selfFilling, testDependsOnDeprecatedLogin); + sendAsyncMessage("doneSetup"); + } +); + +addMessageListener("loadRecipes", async function (recipes) { + var recipeParent = await LoginManagerParent.recipeParentPromise; + await recipeParent.load(recipes); + sendAsyncMessage("loadedRecipes", recipes); +}); + +addMessageListener("resetRecipes", async function () { + let recipeParent = await LoginManagerParent.recipeParentPromise; + await recipeParent.reset(); + sendAsyncMessage("recipesReset"); +}); + +addMessageListener("getTelemetryEvents", options => { + options = Object.assign( + { + filterProps: {}, + clear: false, + }, + options + ); + let snapshots = Services.telemetry.snapshotEvents( + Ci.nsITelemetry.DATASET_PRERELEASE_CHANNELS, + options.clear + ); + let events = options.process in snapshots ? snapshots[options.process] : []; + + // event is array of values like: [22476,"pwmgr","autocomplete_field","generatedpassword"] + let keys = ["id", "category", "method", "object", "value"]; + events = events.filter(entry => { + for (let idx = 0; idx < keys.length; idx++) { + let key = keys[idx]; + if ( + key in options.filterProps && + options.filterProps[key] !== entry[idx] + ) { + return false; + } + } + return true; + }); + sendAsyncMessage("getTelemetryEvents", events); +}); + +addMessageListener("proxyLoginManager", msg => { + // Recreate nsILoginInfo objects from vanilla JS objects. + let recreatedArgs = msg.args.map((arg, index) => { + if (msg.loginInfoIndices.includes(index)) { + return LoginHelper.vanillaObjectToLogin(arg); + } + + return arg; + }); + + let rv = Services.logins[msg.methodName](...recreatedArgs); + if (rv instanceof Ci.nsILoginInfo) { + rv = LoginHelper.loginToVanillaObject(rv); + } else if ( + Array.isArray(rv) && + !!rv.length && + rv[0] instanceof Ci.nsILoginInfo + ) { + rv = rv.map(login => LoginHelper.loginToVanillaObject(login)); + } + return rv; +}); + +addMessageListener("isLoggedIn", () => { + // This can't use the LoginManager proxy in pwmgr_common.js since it's not a method. + return Services.logins.isLoggedIn; +}); + +addMessageListener("setPrimaryPassword", ({ enable }) => { + if (enable) { + LoginTestUtils.primaryPassword.enable(); + } else { + LoginTestUtils.primaryPassword.disable(); + } +}); + +LoginManagerParent.setListenerForTests((msg, { origin, data }) => { + if (msg == "ShowDoorhanger") { + sendAsyncMessage("formSubmissionProcessed", { origin, data }); + } else if (msg == "PasswordEditedOrGenerated") { + sendAsyncMessage("passwordEditedOrGenerated", { origin, data }); + } else if (msg == "FormProcessed") { + sendAsyncMessage("formProcessed", {}); + } +}); + +addMessageListener("cleanup", () => { + LoginManagerParent.setListenerForTests(null); +}); |