summaryrefslogtreecommitdiffstats
path: root/toolkit/components/passwordmgr/test/browser/browser_doorhanger_multipage_form.js
blob: ff7bffcb44edc2f24bf42ec857481b8b083a49d0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
/**
 * Test that the doorhanger notification for password saving is populated with
 * the correct values in various password capture cases (multipage login form).
 */

const testCases = [
  {
    name: "No saved logins, username and password",
    username: "username",
    password: "password",
    expectOutcome: [
      {
        username: "username",
        password: "password",
      },
    ],
  },
  {
    name: "No saved logins, password with empty username",
    username: "",
    password: "password",
    expectOutcome: [
      {
        username: "",
        password: "password",
      },
    ],
  },
  {
    name: "Saved login with username, update password",
    username: "username",
    oldPassword: "password",
    password: "newPassword",
    expectOutcome: [
      {
        username: "username",
        password: "newPassword",
      },
    ],
  },
  {
    name: "Saved login with username, add username",
    oldUsername: "username",
    username: "newUsername",
    password: "password",
    expectOutcome: [
      {
        username: "newUsername",
        password: "password",
      },
    ],
  },
  {
    name: "Saved login with no username, add username and different password",
    oldUsername: "",
    username: "username",
    oldPassword: "password",
    password: "newPassword",
    expectOutcome: [
      {
        username: "",
        password: "password",
      },
      {
        username: "username",
        password: "newPassword",
      },
    ],
  },
];

add_task(async function test_initialize() {
  Services.prefs.setBoolPref("signon.usernameOnlyForm.enabled", true);
  registerCleanupFunction(() => {
    Services.prefs.clearUserPref("signon.usernameOnlyForm.enabled");
  });
});

for (let testData of testCases) {
  let tmp = {
    async [testData.name]() {
      info("testing with: " + JSON.stringify(testData));
      await test_save_change(testData);
    },
  };
  add_task(tmp[testData.name]);
}

async function test_save_change(testData) {
  let { oldUsername, username, oldPassword, password, expectOutcome } =
    testData;
  // Add a login for the origin of the form if testing a change notification.
  if (oldPassword) {
    await Services.logins.addLoginAsync(
      LoginTestUtils.testData.formLogin({
        origin: "https://example.com",
        formActionOrigin: "https://example.com",
        username: typeof oldUsername !== "undefined" ? oldUsername : username,
        password: oldPassword,
      })
    );
  }

  await BrowserTestUtils.withNewTab(
    {
      gBrowser,
      url:
        "https://example.com/browser/toolkit/components/" +
        "passwordmgr/test/browser/form_multipage.html",
    },
    async function (browser) {
      await SimpleTest.promiseFocus(browser.ownerGlobal);

      // Update the username filed from the test case.
      info(`update form with username: ${username}`);
      await changeContentFormValues(browser, {
        "#form-basic-username": username,
      });

      // Submit the username-only form, which then advance to the password-only
      // form.
      info(`submit the username-only form`);
      await SpecialPowers.spawn(browser, [], async function () {
        let doc = this.content.document;
        doc.getElementById("form-basic-submit").click();
        await ContentTaskUtils.waitForCondition(() => {
          return doc.getElementById("form-basic-password");
        }, "Wait for the username field");
      });

      // Update the password filed from the test case.
      info(`update form with password: ${password}`);
      await changeContentFormValues(browser, {
        "#form-basic-password": password,
      });

      // Submit the form.
      info(`submit the password-only form`);
      let formSubmittedPromise = listenForTestNotification("ShowDoorhanger");
      await SpecialPowers.spawn(browser, [], async function () {
        let doc = this.content.document;
        doc.getElementById("form-basic-submit").click();
      });
      await formSubmittedPromise;

      // Simulate the action on the notification to request the login to be
      // saved, and wait for the data to be updated or saved based on the type
      // of operation we expect.
      let expectedNotification, expectedDoorhanger;
      if (oldPassword !== undefined && oldUsername !== undefined) {
        expectedNotification = "addLogin";
        expectedDoorhanger = "password-save";
      } else if (oldPassword !== undefined) {
        expectedNotification = "modifyLogin";
        expectedDoorhanger = "password-change";
      } else {
        expectedNotification = "addLogin";
        expectedDoorhanger = "password-save";
      }

      info("Waiting for doorhanger of type: " + expectedDoorhanger);
      let notif = await waitForDoorhanger(browser, expectedDoorhanger);

      // Check the actual content of the popup notification.
      await checkDoorhangerUsernamePassword(username, password);

      let promiseLogin = TestUtils.topicObserved(
        "passwordmgr-storage-changed",
        (_, data) => data == expectedNotification
      );
      await clickDoorhangerButton(notif, REMEMBER_BUTTON);
      await promiseLogin;
      await cleanupDoorhanger(notif); // clean slate for the next test

      // Check that the values in the database match the expected values.
      verifyLogins(expectOutcome);
    }
  );

  // Clean up the database before the next test case is executed.
  Services.logins.removeAllUserFacingLogins();
}