summaryrefslogtreecommitdiffstats
path: root/toolkit/components/passwordmgr/test/mochitest/test_LoginManagerContent_passwordEditedOrGenerated.html
blob: 9d23177924d6a314e9cdfaf55254929dab1e91a3 (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
<!DOCTYPE HTML>
<html>
<head>
  <meta charset="utf-8">
  <title>Test behavior of unmasking in LMC._passwordEditedOrGenerated</title>
  <script src="/tests/SimpleTest/SimpleTest.js"></script>
  <script src="/tests/SimpleTest/EventUtils.js"></script>
  <script type="text/javascript" src="../../../satchel/test/satchel_common.js"></script>
  <script src="pwmgr_common.js"></script>
  <link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<p id="display"></p>
<div id="content"></div>
<pre id="test"></pre>
<script>
const { LoginManagerChild } = SpecialPowers.ChromeUtils.importESModule(
  "resource://gre/modules/LoginManagerChild.sys.mjs"
);

function preventDefaultAndStopProgagation(event) {
  event.preventDefault();
  event.stopImmediatePropagation();
}

add_setup(async () => {
  await SpecialPowers.pushPrefEnv({"set": [
    ["signon.generation.available", true],
    ["signon.generation.enabled", true],
  ]});
  await setStoredLoginsAsync(
    [location.origin, "https://autofill", null, "user1", "pass1"],
    [location.origin, "https://autofill", null, "user2", "pass2"]
  );
});

add_task(async function prevent_default_and_stop_propagation() {
  const form = createLoginForm({
    action: "https://autofill"
  });
  await promiseFormsProcessedInSameProcess();
  form.pword.focus();

  form.pword.addEventListener("focus", preventDefaultAndStopProgagation);
  form.pword.addEventListener("focus", preventDefaultAndStopProgagation, true);
  form.pword.addEventListener("blur", preventDefaultAndStopProgagation);
  form.pword.addEventListener("blur", preventDefaultAndStopProgagation, true);

  SpecialPowers.wrap(form.pword).setUserInput("generatedpass");
  LOGIN_FIELD_UTILS.checkPasswordMasked(form.pword, true, "Before first fill");
  LoginManagerChild.forWindow(window)._passwordEditedOrGenerated(form.pword, { triggeredByFillingGenerated: true });
  LOGIN_FIELD_UTILS.checkPasswordMasked(form.pword, false, "After first fill");
  synthesizeKey("KEY_Tab"); // blur
  LOGIN_FIELD_UTILS.checkPasswordMasked(form.pword, true, "After blur");
  synthesizeKey("KEY_Tab", { shiftKey: true }); // focus again
  LOGIN_FIELD_UTILS.checkPasswordMasked(form.pword, false, "After shift-tab to focus again");
});

add_task(async function fields_masked_after_saved_login_fill() {
  const form = createLoginForm({
    action: "https://autofill"
  });
  await promiseFormsProcessedInSameProcess();
  form.pword.focus();

  SpecialPowers.wrap(form.pword).setUserInput("generatedpass");
  LOGIN_FIELD_UTILS.checkPasswordMasked(form.pword, true, "Before first fill");
  LoginManagerChild.forWindow(window)._passwordEditedOrGenerated(form.pword, { triggeredByFillingGenerated: true });
  LOGIN_FIELD_UTILS.checkPasswordMasked(form.pword, false, "After first fill");
  synthesizeKey("KEY_Tab", { shiftKey: true }); // blur pw, focus un
  LOGIN_FIELD_UTILS.checkPasswordMasked(form.pword, true, "After blur");

  info("Filling username matching saved login");
  sendString("user1");

  let processedPromise = promiseFormsProcessedInSameProcess();
  synthesizeKey("KEY_Tab"); // focus again and trigger a fill of the matching password
  await processedPromise;
  is(form.pword.value, "pass1", "Saved password was filled")
  LOGIN_FIELD_UTILS.checkPasswordMasked(form.pword, true, "After filling a saved login");
});

add_task(async function fields_masked_after_replacing_whole_value() {
  const form = createLoginForm({
    action: "https://autofill"
  });
  await promiseFormsProcessedInSameProcess();
  form.pword.focus();

  SpecialPowers.wrap(form.pword).setUserInput("generatedpass");
  LOGIN_FIELD_UTILS.checkPasswordMasked(form.pword, true, "Before first fill");
  LoginManagerChild.forWindow(window)._passwordEditedOrGenerated(form.pword, { triggeredByFillingGenerated: true });
  LOGIN_FIELD_UTILS.checkPasswordMasked(form.pword, false, "After first fill");
  synthesizeKey("KEY_Tab", { shiftKey: true }); // blur pw, focus un
  LOGIN_FIELD_UTILS.checkPasswordMasked(form.pword, true, "After blur");

  synthesizeKey("KEY_Tab"); // focus again and replace the whole password value
  info("Replacing password field value with arbitrary string");
  sendString("some_other_password");
  is(form.pword.value, "some_other_password", "Whole password replaced")
  LOGIN_FIELD_UTILS.checkPasswordMasked(form.pword, true, "Replaced password value");

  synthesizeKey("KEY_Tab"); // blur pw
  LOGIN_FIELD_UTILS.checkPasswordMasked(form.pword, true, "After blur");
  synthesizeKey("KEY_Tab", { shiftKey: true }); // focus pw again
  LOGIN_FIELD_UTILS.checkPasswordMasked(form.pword, true, "After focus again");
});

add_task(async function fields_unmasked_after_adding_character() {
  const form = createLoginForm({
    action: "https://autofill"
  });
  await promiseFormsProcessedInSameProcess();
  form.pword.focus();

  SpecialPowers.wrap(form.pword).setUserInput("generatedpass");
  LOGIN_FIELD_UTILS.checkPasswordMasked(form.pword, true, "Before first fill");
  LoginManagerChild.forWindow(window)._passwordEditedOrGenerated(form.pword, { triggeredByFillingGenerated: true });
  LOGIN_FIELD_UTILS.checkPasswordMasked(form.pword, false, "After first fill");
  synthesizeKey("KEY_Tab", { shiftKey: true }); // blur pw, focus un
  LOGIN_FIELD_UTILS.checkPasswordMasked(form.pword, true, "After blur");

  synthesizeKey("KEY_Tab"); // focus again
  synthesizeKey("KEY_ArrowRight"); // Remove the selection
  info("Adding a character to the end of the password");
  sendString("@");
  is(form.pword.value, "generatedpass@", "Character was added to the value")
  LOGIN_FIELD_UTILS.checkPasswordMasked(form.pword, false, "Added @");

  synthesizeKey("KEY_Tab"); // blur pw
  LOGIN_FIELD_UTILS.checkPasswordMasked(form.pword, true, "After blur after @");
  synthesizeKey("KEY_Tab", { shiftKey: true }); // focus pw again
  LOGIN_FIELD_UTILS.checkPasswordMasked(form.pword, false, "After focus after @");
});

add_task(async function type_not_password() {
  const form = createLoginForm({
    action: "https://autofill"
  });
  await promiseFormsProcessedInSameProcess();
  form.pword.focus();

  LOGIN_FIELD_UTILS.checkPasswordMasked(form.pword, true, "Before first fill");
  SpecialPowers.wrap(form.pword).setUserInput("generatedpass");
  LoginManagerChild.forWindow(window)._passwordEditedOrGenerated(form.pword, { triggeredByFillingGenerated: true });
  LOGIN_FIELD_UTILS.checkPasswordMasked(form.pword, false, "After first fill");

  // Simulate a website doing their own unmasking and re-masking
  form.pword.type = "text";
  await new Promise(resolve => SimpleTest.executeSoon(resolve));
  form.pword.type = "password";

  synthesizeKey("KEY_Tab"); // blur
  LOGIN_FIELD_UTILS.checkPasswordMasked(form.pword, true, "After blur");
  synthesizeKey("KEY_Tab", { shiftKey: true }); // focus again
  LOGIN_FIELD_UTILS.checkPasswordMasked(form.pword, false, "After shift-tab to focus again");
});
</script>
</body>
</html>