test_password_unmask_API.html (13747B)
1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <title>Test for unmasking password API</title> 5 <script src="/tests/SimpleTest/SimpleTest.js"></script> 6 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> 7 </head> 8 <body> 9 <input type="text"> 10 <input type="password"> 11 <script class="testbody" type="application/javascript"> 12 SimpleTest.waitForExplicitFinish(); 13 SimpleTest.waitForFocus(() => { 14 let input = document.getElementsByTagName("input")[0]; 15 let password = document.getElementsByTagName("input")[1]; 16 17 let editor, passwordEditor; 18 function updateEditors() { 19 editor = SpecialPowers.wrap(input).editor; 20 passwordEditor = SpecialPowers.wrap(password).editor; 21 } 22 23 try { 24 updateEditors(); 25 editor.mask(); 26 ok(false, 27 `nsIEditor.mask() should throw exception when called for <input type="text"> before nsIEditor.unmask()`); 28 } catch (e) { 29 ok(true, 30 `nsIEditor.mask() should throw exception when called for <input type="text"> before nsIEditor.unmask() ${e}`); 31 } 32 33 try { 34 updateEditors(); 35 editor.unmask(); 36 ok(false, 37 `nsIEditor.unmask() should throw exception when called for <input type="text">`); 38 } catch (e) { 39 ok(true, 40 `nsIEditor.unmask() should throw exception when called for <input type="text"> ${e}`); 41 } 42 43 try { 44 updateEditors(); 45 editor.unmask(0); 46 ok(false, 47 `nsIEditor.unmask(0) should throw exception when called for <input type="text">`); 48 } catch (e) { 49 ok(true, 50 `nsIEditor.unmask(0) should throw exception when called for <input type="text"> ${e}`); 51 } 52 53 input.value = "abcdef"; 54 try { 55 updateEditors(); 56 editor.unmask(); 57 ok(false, 58 `nsIEditor.unmask() should throw exception when called for <input type="text" value="abcdef">`); 59 } catch (e) { 60 ok(true, 61 `nsIEditor.unmask() should throw exception when called for <input type="text" value="abcdef"> ${e}`); 62 } 63 64 try { 65 updateEditors(); 66 editor.mask(); 67 ok(false, 68 `nsIEditor.mask() should throw exception when called for <input type="text" value="abcdef"> after nsIEditor.unmask()`); 69 } catch (e) { 70 ok(true, 71 `nsIEditor.mask() should throw exception when called for <input type="text" value="abcdef"> after nsIEditor.unmask() ${e}`); 72 } 73 74 try { 75 updateEditors(); 76 passwordEditor.mask(); 77 ok(true, 78 `nsIEditor.mask() shouldn't throw exception when called for <input type="password"> before nsIEditor.unmask()`); 79 ok(passwordEditor.autoMaskingEnabled, 80 `nsIEditor.autoMaskingEnabled should be true after nsIEditor.mask() for <input type="password"> before nsIEditor.unmask()`); 81 } catch (e) { 82 ok(false, 83 `nsIEditor.mask() shouldn't throw exception when called for <input type="password"> before nsIEditor.unmask() ${e}`); 84 } 85 86 try { 87 updateEditors(); 88 editor.unmask(5); 89 ok(false, 90 `nsIEditor.unmask(5) should throw exception when called for <input type="password" value="">`); 91 } catch (e) { 92 ok(true, 93 `nsIEditor.unmask(5) should throw exception when called for <input type="password" value=""> ${e}`); 94 ok(passwordEditor.autoMaskingEnabled, 95 `nsIEditor.autoMaskingEnabled should keep true (<input type="password">)`); 96 } 97 98 try { 99 updateEditors(); 100 passwordEditor.unmask(); 101 ok(true, 102 `nsIEditor.unmask() shouldn't throw exception when called for <input type="password">`); 103 ok(!passwordEditor.autoMaskingEnabled, 104 `nsIEditor.autoMaskingEnabled should be false after nsIEditor.unmask() for <input type="password">)`); 105 is(passwordEditor.unmaskedStart, 0, 106 `nsIEditor.unmaskedStart should be 0 after nsIEditor.unmask() for <input type="password">`); 107 is(passwordEditor.unmaskedEnd, 0, 108 `nsIEditor.unmaskedEnd should be 0 after nsIEditor.unmask() for <input type="password">`); 109 } catch (e) { 110 ok(false, 111 `nsIEditor.unmask() shouldn't throw exception when called for <input type="password"> ${e}`); 112 } 113 114 password.value = "abcdef"; 115 try { 116 updateEditors(); 117 passwordEditor.unmask(); 118 ok(true, 119 `nsIEditor.unmask() shouldn't throw exception when called for <input type="password" value="abcdef">)`); 120 ok(!passwordEditor.autoMaskingEnabled, 121 `nsIEditor.autoMaskingEnabled should be false after nsIEditor.unmask() for <input type="password" value="abcdef">`); 122 is(passwordEditor.unmaskedStart, 0, 123 `nsIEditor.unmaskedStart should be 0 after nsIEditor.unmask() for <input type="password" value="abcdef">`); 124 is(passwordEditor.unmaskedEnd, 6, 125 `nsIEditor.unmaskedEnd should be 0 after nsIEditor.unmask() for <input type="password" value="abcdef">`); 126 } catch (e) { 127 ok(false, 128 `nsIEditor.unmask() shouldn't throw exception when called for <input type="password" value="abcdef"> ${e}`); 129 } 130 131 try { 132 updateEditors(); 133 passwordEditor.mask(); 134 ok(true, 135 `nsIEditor.mask() shouldn't throw exception when called for <input type="password" value="abcdef">`); 136 ok(passwordEditor.autoMaskingEnabled, 137 `nsIEditor.autoMaskingEnabled should be true after nsIEditor.mask() for <input type="password" value="abcdef">`); 138 } catch (e) { 139 ok(false, 140 `nsIEditor.mask() shouldn't throw exception when called for <input type="password" value="abcdef"> ${e}`); 141 } 142 143 try { 144 updateEditors(); 145 passwordEditor.unmask(0, 100, 1000); 146 ok(true, 147 `nsIEditor.unmask(0, 100, 1000) shouldn't throw exception when called for <input type="password" value="abcdef">`); 148 ok(passwordEditor.autoMaskingEnabled, 149 `nsIEditor.autoMaskingEnabled should be true after nsIEditor.unmask(0, 100, 1000) for <input type="password" value="abcdef">`); 150 is(passwordEditor.unmaskedStart, 0, 151 `nsIEditor.unmaskedStart should be 0 after nsIEditor.unmask(0, 100, 1000) for <input type="password" value="abcdef">`); 152 is(passwordEditor.unmaskedEnd, 6, 153 `nsIEditor.unmaskedEnd should be 6 after nsIEditor.unmask(0, 100, 1000) for <input type="password" value="abcdef">`); 154 } catch (e) { 155 ok(false, 156 `nsIEditor.unmask(0, 100, 1000) shouldn't throw exception when called for <input type="password" value="abcdef"> ${e}`); 157 } 158 159 try { 160 updateEditors(); 161 passwordEditor.unmask(3); 162 ok(true, 163 `nsIEditor.unmask(3) shouldn't throw exception when called for <input type="password" value="abcdef">`); 164 ok(!passwordEditor.autoMaskingEnabled, 165 `nsIEditor.autoMaskingEnabled should be false after nsIEditor.unmask(3) for <input type="password" value="abcdef">`); 166 is(passwordEditor.unmaskedStart, 3, 167 `nsIEditor.unmaskedStart should be 3 after nsIEditor.unmask(3) for <input type="password" value="abcdef">`); 168 is(passwordEditor.unmaskedEnd, 6, 169 `nsIEditor.unmaskedEnd should be 6 after nsIEditor.unmask(3) for <input type="password" value="abcdef">`); 170 } catch (e) { 171 ok(false, 172 `nsIEditor.unmask(3) shouldn't throw exception when called for <input type="password" value="abcdef"> ${e}`); 173 } 174 175 try { 176 updateEditors(); 177 passwordEditor.unmask(0); 178 password.style.fontSize = "32px"; // reframe the `<input>` element 179 password.getBoundingClientRect(); // flush pending reflow if there is 180 // Then, new `TextEditor` should keep unmasked range. 181 passwordEditor = SpecialPowers.wrap(password).editor; 182 ok(!passwordEditor.autoMaskingEnabled, 183 `nsIEditor.autoMaskingEnabled should be false after the password field reframed`); 184 is(passwordEditor.unmaskedStart, 0, 185 `nsIEditor.unmaskedStart should be 0 after the password field reframed`); 186 is(passwordEditor.unmaskedEnd, 6, 187 `nsIEditor.unmaskedEnd should be 6 after the password field reframed`); 188 } catch (e) { 189 ok(false, `Shouldn't throw exception while testing unmasked range after reframing ${e}`); 190 } finally { 191 password.style.fontSize = ""; 192 password.getBoundingClientRect(); 193 } 194 195 try { 196 updateEditors(); 197 passwordEditor.unmask(0); 198 password.style.display = "none"; // Hide the password field temporarily 199 password.getBoundingClientRect(); 200 password.style.display = "block"; // And show it again 201 password.getBoundingClientRect(); 202 updateEditors(); 203 // Then, new `TextEditor` should keep unmasked range. 204 ok(!passwordEditor.autoMaskingEnabled, 205 `nsIEditor.autoMaskingEnabled should be false after the password field was temporarily hidden`); 206 is(passwordEditor.unmaskedStart, 0, 207 `nsIEditor.unmaskedStart should be 0 after the password field was temporarily hidden`); 208 is(passwordEditor.unmaskedEnd, 6, 209 `nsIEditor.unmaskedEnd should be 6 after the password field was temporarily hidden`); 210 } catch (e) { 211 ok(false, `Shouldn't throw exception while testing unmasked range after temporarily hiding the password field ${e}`); 212 } finally { 213 password.style.display = ""; 214 password.getBoundingClientRect(); 215 passwordEditor = SpecialPowers.wrap(password).editor; 216 } 217 218 try { 219 updateEditors(); 220 passwordEditor.unmask(0); 221 password.style.display = "none"; // Hide the password field temporarily 222 password.getBoundingClientRect(); 223 password.value = "ghijkl"; // And modify the value 224 password.style.display = "block"; // And show it again 225 password.getBoundingClientRect(); 226 // Then, new `TextEditor` shouldn't keep unmasked range due to the value change. 227 updateEditors(); 228 ok(passwordEditor.autoMaskingEnabled, 229 `nsIEditor.autoMaskingEnabled should be true after the password field was temporarily hidden and changed its value`); 230 is(passwordEditor.unmaskedStart, 0, 231 `nsIEditor.unmaskedStart should be 0 after the password field was temporarily hidden and changed its value`); 232 is(passwordEditor.unmaskedEnd, 0, 233 `nsIEditor.unmaskedEnd should be 0 after the password field was temporarily hidden and changed its value`); 234 } catch (e) { 235 ok(false, `Shouldn't throw exception while testing unmasked range after temporarily hiding the password field and changing the value ${e}`); 236 } finally { 237 password.style.display = ""; 238 password.getBoundingClientRect(); 239 password.value = "abcdef"; 240 passwordEditor = SpecialPowers.wrap(password).editor; 241 } 242 243 try { 244 updateEditors(); 245 passwordEditor.unmask(0); 246 password.style.display = "none"; // Hide the password field temporarily 247 password.getBoundingClientRect(); 248 password.value = "abcdef"; // And overwrite the value with same value 249 password.style.display = "block"; // And show it again 250 password.getBoundingClientRect(); 251 // Then, new `TextEditor` shouldn't keep unmasked range due to setting the value. 252 updateEditors(); 253 ok(passwordEditor.autoMaskingEnabled, 254 `nsIEditor.autoMaskingEnabled should be true after the password field was temporarily hidden and changed its value`); 255 is(passwordEditor.unmaskedStart, 0, 256 `nsIEditor.unmaskedStart should be 0 after the password field was temporarily hidden and changed its value`); 257 is(passwordEditor.unmaskedEnd, 0, 258 `nsIEditor.unmaskedEnd should be 0 after the password field was temporarily hidden and changed its value`); 259 } catch (e) { 260 ok(false, `Shouldn't throw exception while testing unmasked range after temporarily hiding the password field and changing the value ${e}`); 261 } finally { 262 password.style.display = ""; 263 password.getBoundingClientRect(); 264 password.value = "abcdef"; 265 passwordEditor = SpecialPowers.wrap(password).editor; 266 } 267 268 try { 269 updateEditors(); 270 passwordEditor.unmask(0, 6, 10000); 271 password.style.display = "none"; // Hide the password field temporarily 272 password.getBoundingClientRect(); 273 password.style.display = "block"; // And show it again 274 password.getBoundingClientRect(); 275 updateEditors(); 276 // Then, new `TextEditor` should mask all characters since nobody can mask it with the timer. 277 ok(passwordEditor.autoMaskingEnabled, 278 `nsIEditor.autoMaskingEnabled should be true after the password field was temporarily hidden (if auto-masking timer was set)`); 279 is(passwordEditor.unmaskedStart, 0, 280 `nsIEditor.unmaskedStart should be 0 after the password field was temporarily hidden (if auto-masking timer was set)`); 281 is(passwordEditor.unmaskedEnd, 0, 282 `nsIEditor.unmaskedEnd should be 0 after the password field was temporarily hidden (if auto-masking timer was set)`); 283 } catch (e) { 284 ok(false, `Shouldn't throw exception while testing unmasked range after temporarily hiding the password field whose auto-masking timer was set ${e}`); 285 } finally { 286 password.style.display = ""; 287 password.getBoundingClientRect(); 288 passwordEditor = SpecialPowers.wrap(password).editor; 289 } 290 291 try { 292 updateEditors(); 293 passwordEditor.unmask(0); 294 password.type = "text"; 295 password.getBoundingClientRect(); 296 password.type = "password"; 297 password.getBoundingClientRect(); 298 updateEditors(); 299 // Then, new `TextEditor` should mask all characters after `type` attribute was changed. 300 ok(passwordEditor.autoMaskingEnabled, 301 `nsIEditor.autoMaskingEnabled should be true after "type" attribute of the password field was changed`); 302 is(passwordEditor.unmaskedStart, 0, 303 `nsIEditor.unmaskedStart should be 0 after "type" attribute of the password field was changed`); 304 is(passwordEditor.unmaskedEnd, 0, 305 `nsIEditor.unmaskedEnd should be 0 after "type" attribute of the password field was changed`); 306 } catch (e) { 307 ok(false, `Shouldn't throw exception while testing unmasked range after "type" attribute of the password field was changed ${e}`); 308 } finally { 309 password.type = "password"; 310 password.getBoundingClientRect(); 311 passwordEditor = SpecialPowers.wrap(password).editor; 312 } 313 314 SimpleTest.finish(); 315 }); 316 </script> 317 </body> 318 </html>