test_clear_form.html (7448B)
1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>Test form autofill - clear form button</title> 6 <script src="/tests/SimpleTest/SimpleTest.js"></script> 7 <script src="/tests/SimpleTest/EventUtils.js"></script> 8 <script type="text/javascript" src="../formautofill_common.js"></script> 9 <script type="text/javascript" src="../../../../../../toolkit/components/satchel/test/satchel_common.js"></script> 10 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> 11 </head> 12 <body> 13 Form autofill test: clear form button 14 15 <script> 16 "use strict"; 17 18 const MOCK_ADDR_STORAGE = [{ 19 organization: "Sesame Street", 20 "street-address": "2 Harrison St\nline2\nline3", 21 tel: "+13453453456", 22 }, { 23 organization: "Mozilla", 24 "street-address": "331 E. Evelyn Avenue", 25 }, { 26 organization: "Tel org", 27 tel: "+12223334444", 28 }]; 29 const MOCK_CC_STORAGE = [{ 30 "cc-name": "John Doe", 31 "cc-number": "4929001587121045", 32 "cc-exp-month": 4, 33 "cc-exp-year": 2017, 34 }, { 35 "cc-name": "Timothy Berners-Lee", 36 "cc-number": "5103059495477870", 37 "cc-exp-month": 12, 38 "cc-exp-year": 2022, 39 }]; 40 41 const MOCK_CC_STORAGE_EXPECTED_FILL = [{ 42 "cc-name": "John Doe", 43 "cc-number": "4929001587121045", 44 "cc-exp-month": "04", 45 "cc-exp-year": 2017, 46 }, { 47 "cc-name": "Timothy Berners-Lee", 48 "cc-number": "5103059495477870", 49 "cc-exp-month": "12", 50 "cc-exp-year": 2022, 51 }]; 52 53 initPopupListener(); 54 55 add_task(async function setup_storage() { 56 await addAddress(MOCK_ADDR_STORAGE[0]); 57 await addAddress(MOCK_ADDR_STORAGE[1]); 58 await addAddress(MOCK_ADDR_STORAGE[2]); 59 60 await addCreditCard(MOCK_CC_STORAGE[0]); 61 await addCreditCard(MOCK_CC_STORAGE[1]); 62 }); 63 64 65 async function checkIsFormCleared(patch = {}) { 66 const form = document.getElementById("form1"); 67 68 for (const elem of form.elements) { 69 const expectedValue = patch[elem.id] || ""; 70 checkFieldValue(elem, expectedValue); 71 await checkFieldHighlighted(elem, false); 72 } 73 } 74 75 async function confirmClear(selector) { 76 info("Await for clearing input"); 77 let promise = new Promise(resolve => { 78 let beforeInputFired = false; 79 let element = document.querySelector(selector); 80 element.addEventListener("beforeinput", (event) => { 81 beforeInputFired = true; 82 ok(event instanceof InputEvent, 83 '"beforeinput" event should be dispatched with InputEvent interface'); 84 is(event.cancelable, SpecialPowers.getBoolPref("dom.input_event.allow_to_cancel_set_user_input"), 85 `"beforeinput" event should be cancelable unless it's disabled by the pref`); 86 is(event.bubbles, true, 87 '"beforeinput" event should always bubble'); 88 is(event.inputType, "insertReplacementText", 89 'inputType value of "beforeinput" should be "insertReplacementText"'); 90 is(event.data, "", 91 'data value of "beforeinput" should be empty string'); 92 is(event.dataTransfer, null, 93 'dataTransfer value of "beforeinput" should be null'); 94 is(event.getTargetRanges().length, 0, 95 'getTargetRanges() of "beforeinput" event should return empty array'); 96 }, {once: true}); 97 element.addEventListener("input", (event) => { 98 ok(beforeInputFired, `"beforeinput" event should've been fired before "input" on <${element.tagName} type="${element.type}">`); 99 ok(event instanceof InputEvent, 100 '"input" event should be dispatched with InputEvent interface'); 101 is(event.cancelable, false, 102 '"input" event should be never cancelable'); 103 is(event.bubbles, true, 104 '"input" event should always bubble'); 105 is(event.inputType, "insertReplacementText", 106 'inputType value of "input" should be "insertReplacementText"'); 107 is(event.data, "", 108 'data value of "input" should be empty string'); 109 is(event.dataTransfer, null, 110 'dataTransfer value of "input" should be null'); 111 is(event.getTargetRanges().length, 0, 112 'getTargetRanges() of "input" should return empty array'); 113 resolve(); 114 }, {once: true}) 115 }); 116 synthesizeKey("KEY_Enter"); 117 await promise; 118 } 119 120 add_task(async function simple_clear() { 121 await triggerPopupAndHoverItem("#organization", 0); 122 await triggerAutofillAndCheckProfile(MOCK_ADDR_STORAGE[0]); 123 124 await triggerPopupAndHoverItem("#tel", 0); 125 await confirmClear("#tel"); 126 await checkIsFormCleared(); 127 128 // Ensure the correctness of the autocomplete popup after the form is cleared 129 synthesizeKey("KEY_ArrowDown"); 130 await expectPopup(); 131 132 is(4, getMenuEntries().labels.length, `Checking length of expected menu`); 133 }); 134 135 add_task(async function clear_adapted_record() { 136 await triggerPopupAndHoverItem("#street-address", 0); 137 await triggerAutofillAndCheckProfile(MOCK_ADDR_STORAGE[0]); 138 139 await triggerPopupAndHoverItem("#street-address", 0); 140 await confirmClear("#street-address"); 141 await checkIsFormCleared(); 142 }); 143 144 add_task(async function clear_modified_form() { 145 await triggerPopupAndHoverItem("#organization", 0); 146 await triggerAutofillAndCheckProfile(MOCK_ADDR_STORAGE[0]); 147 148 await setInput("#tel", "+1111111111", true); 149 150 await triggerPopupAndHoverItem("#street-address", 0); 151 await confirmClear("#street-address"); 152 await checkIsFormCleared({tel: "+1111111111"}); 153 }); 154 155 add_task(async function clear_distinct_section() { 156 if (!(await canTestOSKeyStoreLogin())) { 157 todo(false, "Cannot test OS key store login on official builds."); 158 return; 159 } 160 161 document.getElementById("form1").reset(); 162 await triggerPopupAndHoverItem("#cc-name", 0); 163 let osKeyStoreLoginShown = Promise.resolve(); 164 if(OSKeyStore.canReauth()) { 165 osKeyStoreLoginShown = waitForOSKeyStoreLogin(true); 166 await waitForOSKeyStoreLoginTestSetupComplete(); 167 } 168 await triggerAutofillAndCheckProfile(MOCK_CC_STORAGE_EXPECTED_FILL[0]); 169 await osKeyStoreLoginShown; 170 171 await triggerPopupAndHoverItem("#organization", 0); 172 await triggerAutofillAndCheckProfile(MOCK_ADDR_STORAGE[0]); 173 await triggerPopupAndHoverItem("#street-address", 0); 174 await confirmClear("#street-address"); 175 176 for (const [id, val] of Object.entries(MOCK_CC_STORAGE_EXPECTED_FILL[0])) { 177 const element = document.getElementById(id); 178 if (!element) { 179 return; 180 } 181 checkFieldValue(element, val); 182 await checkFieldHighlighted(element, true); 183 } 184 185 await triggerPopupAndHoverItem("#cc-name", 0); 186 await confirmClear("#cc-name"); 187 await checkIsFormCleared(); 188 // Enforcing this since it is unable to change back in chaos mode. 189 SpecialPowers.clearUserPref("toolkit.osKeyStore.unofficialBuildOnlyLogin"); 190 }); 191 192 </script> 193 194 <p id="display"></p> 195 196 <div id="content"> 197 198 <form id="form1"> 199 <p>This is a basic form.</p> 200 <p><label>organization: <input id="organization" autocomplete="organization"></label></p> 201 <p><label>streetAddress: <input id="street-address" autocomplete="street-address"></label></p> 202 <p><label>tel: <input id="tel" autocomplete="tel"></label></p> 203 <p><label>country: <input id="country" autocomplete="country"></label></p> 204 205 <p><label>Name: <input id="cc-name" autocomplete="cc-name"></label></p> 206 <p><label>Card Number: <input id="cc-number" autocomplete="cc-number"></label></p> 207 <p><label>Expiration month: <input id="cc-exp-month" autocomplete="cc-exp-month"></label></p> 208 <p><label>Expiration year: <input id="cc-exp-year" autocomplete="cc-exp-year"></label></p> 209 <p><label>CSC: <input id="cc-csc" autocomplete="cc-csc"></label></p> 210 </form> 211 212 </div> 213 214 <pre id="test"></pre> 215 </body> 216 </html>