summaryrefslogtreecommitdiffstats
path: root/toolkit/components/passwordmgr/test/mochitest/pwmgr_common_parent.js
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/passwordmgr/test/mochitest/pwmgr_common_parent.js')
-rw-r--r--toolkit/components/passwordmgr/test/mochitest/pwmgr_common_parent.js249
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);
+});