test_findLabelElements.js (9521B)
1 "use strict"; 2 3 var { LabelUtils } = ChromeUtils.importESModule( 4 "resource://gre/modules/shared/LabelUtils.sys.mjs" 5 ); 6 7 const TESTCASES = [ 8 { 9 description: "Input contains in a label element.", 10 document: `<form> 11 <label id="labelA"> label type A 12 <input id="typeA" type="text"> 13 </label> 14 </form>`, 15 expectedLabelIds: [["labelA"]], 16 expectedText: ["label type A"], 17 }, 18 { 19 description: "Input contains in a label element.", 20 document: `<label id="labelB"> label type B 21 <div> inner div 22 <input id="typeB" type="text"> 23 </div> 24 </label>`, 25 inputId: "typeB", 26 expectedLabelIds: [["labelB"]], 27 expectedText: ["label type B inner div"], 28 }, 29 { 30 description: '"for" attribute used to indicate input by one label.', 31 document: `<label id="labelC" for="typeC">label type C</label> 32 <input id="typeC" type="text">`, 33 inputId: "typeC", 34 expectedLabelIds: [["labelC"]], 35 expectedText: [""], 36 }, 37 { 38 description: '"for" attribute used to indicate input by multiple labels.', 39 document: `<form> 40 <label id="labelD1" for="typeD">label type D1</label> 41 <label id="labelD2" for="typeD">label type D2</label> 42 <label id="labelD3" for="typeD">label type D3</label> 43 <input id="typeD" type="text"> 44 </form>`, 45 inputId: "typeD", 46 expectedLabelIds: [["labelD1", "labelD2", "labelD3"]], 47 expectedText: [""], 48 }, 49 { 50 description: 51 '"for" attribute used to indicate input by multiple labels with space prefix/postfix.', 52 document: `<label id="labelE1" for="typeE">label type E1</label> 53 <label id="labelE2" for="typeE ">label type E2</label> 54 <label id="labelE3" for=" TYPEe">label type E3</label> 55 <label id="labelE4" for=" typeE ">label type E4</label> 56 <input id=" typeE " type="text">`, 57 inputId: " typeE ", 58 expectedLabelIds: [["labelE4"]], 59 expectedText: [""], 60 }, 61 { 62 description: "Input contains in a label element.", 63 document: `<label id="labelF"> label type F 64 <label for="dummy"> inner label 65 <input id="typeF" type="text"> 66 <input id="dummy" type="text"> 67 </div> 68 </label>`, 69 inputId: "typeF", 70 expectedLabelIds: [["labelF"], [""]], 71 expectedText: ["inner label", ""], 72 }, 73 { 74 description: 75 '"for" attribute used to indicate input by labels out of the form.', 76 document: `<label id="labelG1" for="typeG">label type G1</label> 77 <form> 78 <label id="labelG2" for="typeG">label type G2</label> 79 <input id="typeG" type="text"> 80 </form> 81 <label id="labelG3" for="typeG">label type G3</label>`, 82 inputId: "typeG", 83 expectedLabelIds: [["labelG1", "labelG2", "labelG3"]], 84 expectedText: [""], 85 }, 86 { 87 description: 88 "labels with no for attribute or child with one input at a different level", 89 document: `<form> 90 <label id="labelH1">label H1</label> 91 <input> 92 <label id="labelH2">label H2</label> 93 <div><span><input></span></div> 94 </form>`, 95 inputId: "labelH1", 96 expectedLabelIds: [["labelH1"], ["labelH2"]], 97 expectedText: ["", ""], 98 }, 99 { 100 description: 101 "labels with no for attribute or child with an input and button", 102 document: `<form> 103 <label id="labelI1">label I1</label> 104 <input> 105 <label id="labelI2">label I2</label> 106 <button> 107 <input> 108 </form>`, 109 inputId: "labelI1", 110 expectedLabelIds: [["labelI1"], []], 111 expectedText: ["", ""], 112 }, 113 { 114 description: "three labels with no for attribute or child.", 115 document: `<form> 116 <button> 117 <label id="labelJ1">label J1</label> 118 <label id="labelJ2">label J2</label> 119 <input> 120 <label id="labelJ3">label J3</label> 121 <meter> 122 <input> 123 </form>`, 124 inputId: "labelJ1", 125 expectedLabelIds: [["labelJ2"], []], 126 expectedText: ["", ""], 127 }, 128 { 129 description: "four labels with no for attribute or child.", 130 document: `<form> 131 <input> 132 <fieldset> 133 <label id="labelK1">label K1</label> 134 <label id="labelK2">label K2</label> 135 <input> 136 <label id="labelK3">label K3</label> 137 <div><b><input></b></div> 138 <label id="labelK4">label K4</label> 139 </fieldset> 140 <input> 141 </form>`, 142 inputId: "labelK1", 143 expectedLabelIds: [[], ["labelK2"], ["labelK3"], []], 144 expectedText: ["", "", "", ""], 145 }, 146 { 147 description: 148 "labels with no for attribute or child and inputs at different level.", 149 document: `<form> 150 <input> 151 <div><span><input></span></div> 152 <label id="labelL1">label L1</label> 153 <label id="labelL2">label L2</label> 154 <div><span><input></span></div> 155 </input> 156 </form>`, 157 inputId: "labelK1", 158 expectedLabelIds: [[], [], ["labelL2"], []], 159 expectedText: ["", "", "", ""], 160 }, 161 { 162 description: "input fields with no labels.", 163 document: `<form> 164 First Name: <input id="inputL1"> 165 Additional Name: <input> 166 Last Name: <input> 167 <span>Telephone</span>: <input> 168 <span>Country:</span><select><option>France<option>Germany</select> 169 <span>Email <b>address</b>:</span><input id="inputL2"> 170 </form>`, 171 inputId: "inputL1", 172 expectedLabelIds: [[], [], [], [], [], []], 173 expectedText: [ 174 "First Name:", 175 "Additional Name:", 176 "Last Name:", 177 "Telephone:", 178 "Country:", 179 "Email address:", 180 ], 181 }, 182 { 183 description: "input fields with no labels and mixed labels.", 184 document: `<form> 185 First Name: <input id="inputM1"> 186 Last <output>output</output>Name: <input> 187 <div><span>Telephone</span></div>: <input> 188 <input> 189 <label id="labelL1" for="inputM1">Given Name</label> 190 </form>`, 191 inputId: "inputM1", 192 expectedLabelIds: [["labelL1"], [], [], []], 193 expectedText: ["First Name:", "Name:", "Telephone:", ""], 194 }, 195 { 196 description: "input fields with no labels with deeply nested text.", 197 document: `<form> 198 <p><span><b>First Name</b></span</p>: <input id="inputN1"> 199 <p><span><i> Last Name </i> </span </p> : <p><span><input></span></p> 200 <div><div><div><div><div>Telephone</div></div> Number:</div></div></div><input> 201 <p><input>Text</p> 202 </form>`, 203 inputId: "inputN1", 204 expectedLabelIds: [[], [], [], []], 205 expectedText: ["First Name:", "Last Name :", "Telephone Number:", ""], 206 }, 207 { 208 description: 209 "input fields with no labels and other elements that shouldn't be labels.", 210 document: `<form> 211 Please fill in: 212 <fieldset>First Name</fieldset><input id="inputO1"> 213 (Optional) 214 <button>Last Name</button><input> 215 Telephone<input> 216 <p><input>Text</p> 217 </form>`, 218 inputId: "inputO1", 219 expectedLabelIds: [[], [], [], []], 220 expectedText: ["", "", "Telephone", ""], 221 }, 222 { 223 description: "input fields labels in other languages.", 224 document: `<form> 225 이름 <input id="inputP1"> 226 മറുപേര് <input> 227 <span>телефон</span>: <input> 228 </form>`, 229 inputId: "inputP1", 230 expectedLabelIds: [[], [], []], 231 expectedText: ["이름", "മറുപേര്", "телефон:"], 232 }, 233 { 234 description: "input fields with labels too far away.", 235 document: `<form> 236 <span><b>Hello</b> 237 <span><span><span><span><span> 238 </span></span></span></span></span> 239 <input id="inputQ1"> 240 <span><b>Goodbye</b> 241 <span><span><span><span><span><span> 242 </span></span></span></span></span></span> 243 <input id="inputQ2"> 244 </form>`, 245 inputId: "inputQ1", 246 expectedLabelIds: [[], []], 247 expectedText: ["Hello", ""], 248 }, 249 ]; 250 251 TESTCASES.forEach(testcase => { 252 add_task(async function () { 253 info("Starting testcase: " + testcase.description); 254 255 let doc = MockDocument.createTestDocument( 256 "http://localhost:8080/test/", 257 testcase.document 258 ); 259 260 let formElements = doc.querySelectorAll("input, select"); 261 let labelsIndex = 0; 262 for (let formElement of formElements) { 263 let labels = LabelUtils.findLabelElements(formElement); 264 Assert.deepEqual( 265 labels.map(l => l.id), 266 testcase.expectedLabelIds[labelsIndex] 267 ); 268 269 let text = LabelUtils.findNearbyText(formElement); 270 Assert.deepEqual(text, testcase.expectedText[labelsIndex]); 271 labelsIndex++; 272 } 273 274 LabelUtils.clearLabelMap(); 275 }); 276 });