Bug 1549814 - Add automated tests for creating a login. r?MattN draft
authorpulselistener
Sat, 18 May 2019 06:49:27 +0000
changeset 2008575 e1fb67d904f884b8220b870ad7f057a621c0a4bc
parent 2008574 125909675145ef08262d8459821b1221087cadf4
child 2008576 6eb4ec2cb49f7ae291426d59a4906e7d486c5c15
push id363923
push userreviewbot
push dateSat, 18 May 2019 06:49:52 +0000
treeherdertry@6eb4ec2cb49f [default view] [failures only]
reviewersMattN
bugs1549814
milestone68.0a1
Bug 1549814 - Add automated tests for creating a login. r?MattN Differential Revision: https://phabricator.services.mozilla.com/D31714 Differential Diff: PHID-DIFF-kicuyivgzqgpophreg3i
browser/components/aboutlogins/tests/mochitest/test_login_item.html
browser/components/aboutlogins/tests/mochitest/test_reflected_fluent_element.html
--- a/browser/components/aboutlogins/tests/mochitest/test_login_item.html
+++ b/browser/components/aboutlogins/tests/mochitest/test_login_item.html
@@ -49,83 +49,175 @@ add_task(async function setup() {
   importDependencies(templateFrame, displayEl);
 
   gLoginItem = document.createElement("login-item");
   displayEl.appendChild(gLoginItem);
 });
 
 add_task(async function test_empty_item() {
   ok(gLoginItem, "loginItem exists");
-  is(gLoginItem.shadowRoot.querySelector(".hostname").textContent, "", "hostname should be blank");
+  is(gLoginItem.shadowRoot.querySelector(".hostname-saved-value").textContent, "", "hostname should be blank");
   is(gLoginItem.shadowRoot.querySelector("modal-input[name='username']").value, "", "username should be blank");
   is(gLoginItem.shadowRoot.querySelector("modal-input[name='password']").value, "", "password should be blank");
-  is(gLoginItem.shadowRoot.querySelector(".time-created").textContent, "", "time-created should be blank");
-  is(gLoginItem.shadowRoot.querySelector(".time-changed").textContent, "", "time-changed should be blank");
-  is(gLoginItem.shadowRoot.querySelector(".time-used").textContent, "", "time-used should be blank");
+  is(gLoginItem.shadowRoot.querySelector(".time-created").textContent, "0", "time-created should be 0 when undefined");
+  is(gLoginItem.shadowRoot.querySelector(".time-changed").textContent, "0", "time-changed should be 0 when undefined");
+  is(gLoginItem.shadowRoot.querySelector(".time-used").textContent, "0", "time-used should be 0 when undefined");
 });
 
 add_task(async function test_set_login() {
   gLoginItem.setLogin(TEST_LOGIN_1);
   await asyncElementRendered();
 
-  is(gLoginItem.shadowRoot.querySelector(".hostname").textContent, TEST_LOGIN_1.hostname, "hostname should be populated");
+  ok(!gLoginItem.hasAttribute("editing"), "loginItem should not be in 'edit' mode");
+  ok(!gLoginItem.hasAttribute("isNewLogin"), "loginItem should not be in 'isNewLogin' mode");
+  let savedHostname = gLoginItem.shadowRoot.querySelector(".hostname-saved-value");
+  is(getComputedStyle(savedHostname).display, "inline", ".hostname-saved-value should be visible for non-editing existing logins");
+  let hostnameInput = gLoginItem.shadowRoot.querySelector("input[name='hostname']");
+  is(getComputedStyle(hostnameInput).display, "none", "input[name='hostname'] should be hidden for non-editing existing logins");
+  is(savedHostname.textContent, TEST_LOGIN_1.hostname, "hostname should be populated");
   is(gLoginItem.shadowRoot.querySelector("modal-input[name='username']").value, TEST_LOGIN_1.username, "username should be populated");
   is(gLoginItem.shadowRoot.querySelector("modal-input[name='password']").value, TEST_LOGIN_1.password, "password should be populated");
   is(gLoginItem.shadowRoot.querySelector(".time-created").textContent, TEST_LOGIN_1.timeCreated, "time-created should be populated");
   is(gLoginItem.shadowRoot.querySelector(".time-changed").textContent, TEST_LOGIN_1.timePasswordChanged, "time-changed should be populated");
   is(gLoginItem.shadowRoot.querySelector(".time-used").textContent, TEST_LOGIN_1.timeLastUsed, "time-used should be populated");
 });
 
+add_task(async function test_edit_login() {
+  gLoginItem.setLogin(TEST_LOGIN_1);
+  gLoginItem.shadowRoot.querySelector(".edit-button").click();
+  await asyncElementRendered();
+
+  ok(gLoginItem.hasAttribute("editing"), "loginItem should be in 'edit' mode");
+  ok(!gLoginItem.hasAttribute("isNewLogin"), "loginItem should not be in 'isNewLogin' mode");
+  let savedHostname = gLoginItem.shadowRoot.querySelector(".hostname-saved-value");
+  is(getComputedStyle(savedHostname).display, "inline", ".hostname-saved-value should be visible for editing existing logins");
+  let hostnameInput = gLoginItem.shadowRoot.querySelector("input[name='hostname']");
+  is(getComputedStyle(hostnameInput).display, "none", "input[name='hostname'] should be hidden for editing existing logins");
+  is(savedHostname.textContent, TEST_LOGIN_1.hostname, "hostname should be populated");
+  is(gLoginItem.shadowRoot.querySelector("modal-input[name='username']").value, TEST_LOGIN_1.username, "username should be populated");
+  is(gLoginItem.shadowRoot.querySelector("modal-input[name='password']").value, TEST_LOGIN_1.password, "password should be populated");
+  is(gLoginItem.shadowRoot.querySelector(".time-created").textContent, TEST_LOGIN_1.timeCreated, "time-created should be populated");
+  is(gLoginItem.shadowRoot.querySelector(".time-changed").textContent, TEST_LOGIN_1.timePasswordChanged, "time-changed should be populated");
+  is(gLoginItem.shadowRoot.querySelector(".time-used").textContent, TEST_LOGIN_1.timeLastUsed, "time-used should be populated");
+
+  gLoginItem.shadowRoot.querySelector("modal-input[name='username']").value = "newUsername";
+  gLoginItem.shadowRoot.querySelector("modal-input[name='password']").value = "newPassword";
+
+  let updateEventDispatched = false;
+  document.addEventListener("AboutLoginsUpdateLogin", event => {
+    is(event.detail.guid, TEST_LOGIN_1.guid, "event should include guid");
+    is(event.detail.hostname, TEST_LOGIN_1.hostname, "event should include hostname");
+    is(event.detail.username, "newUsername", "event should include new username");
+    is(event.detail.password, "newPassword", "event should include new password");
+    updateEventDispatched = true;
+  }, {once: true});
+  gLoginItem.shadowRoot.querySelector(".save-changes-button").click();
+  ok(updateEventDispatched, "Clicking the .save-changes-button should dispatch the AboutLoginsUpdateLogin event");
+});
+
+add_task(async function test_edit_login_cancel() {
+  for (let login of [{}, TEST_LOGIN_1]) {
+    let isNewLogin = !login.username;
+    info("Testing with" + (isNewLogin ? "out" : "") + " a login");
+    gLoginItem.setLogin(login);
+    gLoginItem.shadowRoot.querySelector(".edit-button").click();
+
+    ok(gLoginItem.hasAttribute("editing"), "loginItem should be in 'edit' mode");
+    is(gLoginItem.hasAttribute("isNewLogin"), isNewLogin,
+       "loginItem should " + (isNewLogin ? "" : "not ") + "be in 'isNewLogin' mode");
+
+    gLoginItem.shadowRoot.querySelector(".cancel-button").click();
+    ok(!gLoginItem.hasAttribute("editing"), "loginItem should not be in 'edit' mode");
+    ok(!gLoginItem.hasAttribute("isNewLogin"), "loginItem should not be in 'isNewLogin' mode");
+  }
+});
+
+add_task(async function test_set_login_empty() {
+  gLoginItem.setLogin({});
+  await asyncElementRendered();
+
+  ok(gLoginItem.hasAttribute("editing"), "loginItem should be in 'edit' mode");
+  ok(gLoginItem.hasAttribute("isNewLogin"), "loginItem should be in 'isNewLogin' mode");
+  let savedHostname = gLoginItem.shadowRoot.querySelector(".hostname-saved-value");
+  is(getComputedStyle(savedHostname).display, "none", ".hostname-saved-value should be hidden for new logins");
+  let hostnameInput = gLoginItem.shadowRoot.querySelector("input[name='hostname']");
+  is(getComputedStyle(hostnameInput).display, "inline", "input[name='hostname'] should be visible for new logins");
+  is(gLoginItem.shadowRoot.querySelector("modal-input[name='username']").value, "", "username should be empty");
+  is(gLoginItem.shadowRoot.querySelector("modal-input[name='password']").value, "", "password should be empty");
+  is(gLoginItem.shadowRoot.querySelector(".time-created").textContent, "0", "time-created should be 0 when undefined");
+  is(gLoginItem.shadowRoot.querySelector(".time-changed").textContent, "0", "time-changed should be 0 when undefined");
+  is(gLoginItem.shadowRoot.querySelector(".time-used").textContent, "0", "time-used should be 0 when undefined");
+
+  hostnameInput.value = "https://example.com/foo";
+  gLoginItem.shadowRoot.querySelector("modal-input[name='username']").value = "user1";
+  gLoginItem.shadowRoot.querySelector("modal-input[name='password']").value = "pass1";
+
+  let createEventDispatched = false;
+  document.addEventListener("AboutLoginsCreateLogin", event => {
+    is(event.detail.guid, undefined, "event should not include guid");
+    is(event.detail.hostname, "https://example.com/foo", "event should include hostname");
+    is(event.detail.username, "user1", "event should include new username");
+    is(event.detail.password, "pass1", "event should include new password");
+    createEventDispatched = true;
+  }, {once: true});
+  gLoginItem.shadowRoot.querySelector(".save-changes-button").click();
+  ok(createEventDispatched, "Clicking the .save-changes-button should dispatch the AboutLoginsCreateLogin event");
+});
+
 add_task(async function test_different_login_modified() {
+  gLoginItem.setLogin(TEST_LOGIN_1);
   let otherLogin = Object.assign({}, TEST_LOGIN_1, {username: "fakeuser", guid: "fakeguid"});
   gLoginItem.loginModified(otherLogin);
   await asyncElementRendered();
 
-  is(gLoginItem.shadowRoot.querySelector(".hostname").textContent, TEST_LOGIN_1.hostname, "hostname should be unchanged");
+  is(gLoginItem.shadowRoot.querySelector(".hostname-saved-value").textContent, TEST_LOGIN_1.hostname, "hostname should be unchanged");
   is(gLoginItem.shadowRoot.querySelector("modal-input[name='username']").value, TEST_LOGIN_1.username, "username should be unchanged");
   is(gLoginItem.shadowRoot.querySelector("modal-input[name='password']").value, TEST_LOGIN_1.password, "password should be unchanged");
   is(gLoginItem.shadowRoot.querySelector(".time-created").textContent, TEST_LOGIN_1.timeCreated, "time-created should be unchanged");
   is(gLoginItem.shadowRoot.querySelector(".time-changed").textContent, TEST_LOGIN_1.timePasswordChanged, "time-changed should be unchanged");
   is(gLoginItem.shadowRoot.querySelector(".time-used").textContent, TEST_LOGIN_1.timeLastUsed, "time-used should be unchanged");
 });
 
 add_task(async function test_different_login_removed() {
+  gLoginItem.setLogin(TEST_LOGIN_1);
   let otherLogin = Object.assign({}, TEST_LOGIN_1, {username: "fakeuser", guid: "fakeguid"});
   gLoginItem.loginRemoved(otherLogin);
   await asyncElementRendered();
 
-  is(gLoginItem.shadowRoot.querySelector(".hostname").textContent, TEST_LOGIN_1.hostname, "hostname should be unchanged");
+  is(gLoginItem.shadowRoot.querySelector(".hostname-saved-value").textContent, TEST_LOGIN_1.hostname, "hostname should be unchanged");
   is(gLoginItem.shadowRoot.querySelector("modal-input[name='username']").value, TEST_LOGIN_1.username, "username should be unchanged");
   is(gLoginItem.shadowRoot.querySelector("modal-input[name='password']").value, TEST_LOGIN_1.password, "password should be unchanged");
   is(gLoginItem.shadowRoot.querySelector(".time-created").textContent, TEST_LOGIN_1.timeCreated, "time-created should be unchanged");
   is(gLoginItem.shadowRoot.querySelector(".time-changed").textContent, TEST_LOGIN_1.timePasswordChanged, "time-changed should be unchanged");
   is(gLoginItem.shadowRoot.querySelector(".time-used").textContent, TEST_LOGIN_1.timeLastUsed, "time-used should be unchanged");
 });
 
 add_task(async function test_login_modified() {
+  gLoginItem.setLogin(TEST_LOGIN_1);
   let modifiedLogin = Object.assign({}, TEST_LOGIN_1, {username: "updateduser"});
   gLoginItem.loginModified(modifiedLogin);
   await asyncElementRendered();
 
-  is(gLoginItem.shadowRoot.querySelector(".hostname").textContent, modifiedLogin.hostname, "hostname should be updated");
+  is(gLoginItem.shadowRoot.querySelector(".hostname-saved-value").textContent, modifiedLogin.hostname, "hostname should be updated");
   is(gLoginItem.shadowRoot.querySelector("modal-input[name='username']").value, modifiedLogin.username, "username should be updated");
   is(gLoginItem.shadowRoot.querySelector("modal-input[name='password']").value, modifiedLogin.password, "password should be updated");
   is(gLoginItem.shadowRoot.querySelector(".time-created").textContent, modifiedLogin.timeCreated, "time-created should be updated");
   is(gLoginItem.shadowRoot.querySelector(".time-changed").textContent, modifiedLogin.timePasswordChanged, "time-changed should be updated");
   is(gLoginItem.shadowRoot.querySelector(".time-used").textContent, modifiedLogin.timeLastUsed, "time-used should be updated");
 });
 
 add_task(async function test_login_removed() {
+  gLoginItem.setLogin(TEST_LOGIN_1);
   gLoginItem.loginRemoved(TEST_LOGIN_1);
   await asyncElementRendered();
 
-  is(gLoginItem.shadowRoot.querySelector(".hostname").textContent, "", "hostname should be cleared");
+  is(gLoginItem.shadowRoot.querySelector(".hostname-saved-value").textContent, "", "hostname should be cleared");
   is(gLoginItem.shadowRoot.querySelector("modal-input[name='username']").value, "", "username should be cleared");
   is(gLoginItem.shadowRoot.querySelector("modal-input[name='password']").value, "", "password should be cleared");
-  is(gLoginItem.shadowRoot.querySelector(".time-created").textContent, "", "time-created should be cleared");
-  is(gLoginItem.shadowRoot.querySelector(".time-changed").textContent, "", "time-changed should be cleared");
-  is(gLoginItem.shadowRoot.querySelector(".time-used").textContent, "", "time-used should be cleared");
+  is(gLoginItem.shadowRoot.querySelector(".time-created").textContent, "0", "time-created should be 0 when undefined");
+  is(gLoginItem.shadowRoot.querySelector(".time-changed").textContent, "0", "time-changed should be 0 when undefined");
+  is(gLoginItem.shadowRoot.querySelector(".time-used").textContent, "0", "time-used should be 0 when undefined");
 });
 
 </script>
 
 </body>
 </html>
--- a/browser/components/aboutlogins/tests/mochitest/test_reflected_fluent_element.html
+++ b/browser/components/aboutlogins/tests/mochitest/test_reflected_fluent_element.html
@@ -30,19 +30,19 @@ const TEST_STRINGS = {
   },
   loginItem: {
     "cancel-button": "Cancel",
     "delete-button": "Delete",
     "hostname-label": "Website Address",
     "password-label": "Password",
     "save-changes-button": "Save Changes",
     // See stubFluentL10n for the following three
-    "time-created": "",
-    "time-changed": "",
-    "time-used": "",
+    "time-created": "0",
+    "time-changed": "0",
+    "time-used": "0",
     "username-label": "Username",
   },
 };
 
 let gLoginFilter;
 let gLoginItem;
 add_task(async function setup() {
   stubFluentL10n({