tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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>