test_document_wireframe.html (10293B)
1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>Tests for document.getWireframe()</title> 6 <script src="/tests/SimpleTest/SimpleTest.js"></script> 7 <link rel="stylesheet" href="/tests/SimpleTest/test.css"/> 8 <script> 9 /** 10 * This test creates some simple webpages, captures wireframes for them, and 11 * then compares them against some expected wireframe structures. 12 */ 13 14 /** 15 * Converts some RGB values into the same uint32_t nsColor representation 16 * that getWireframe uses. 17 * 18 * @param {number} r 19 * Red color value. 20 * @param {number} g 21 * Green color value. 22 * @param {number} b 23 * Blue color value. 24 * @returns {number} 25 * The red, green and blue values composed in a single uint32_t-compatible 26 * value. 27 */ 28 function nscolor(r, g, b) { 29 return (255 << 24 | b << 16 | g << 8 | r) >>> 0; 30 } 31 32 const WHITE_NSCOLOR = nscolor(255, 255, 255); 33 34 const RED_RGB = "rgb(255, 0, 0)"; 35 const RED_NSCOLOR = nscolor(255, 0, 0); 36 const GREEN_RGB = "rgb(0, 255, 0)"; 37 const GREEN_NSCOLOR = nscolor(0, 255, 0); 38 const BLUE_RGB = "rgb(0, 0, 255)"; 39 const BLUE_NSCOLOR = nscolor(0, 0, 255); 40 const BLACK_RGB = "rgb(0, 0, 0)"; 41 const BLACK_NSCOLOR = nscolor(0, 0, 0); 42 const BUILDER = "http://mochi.test:8888/document-builder.sjs?html="; 43 const TEST_PATH = "http://mochi.test:8888/tests/dom/base/test/"; 44 45 /** 46 * This array contains the definition of each test. Each test is an object 47 * that expects two properties: 48 * 49 * {String} html 50 * The markup to be loaded in the page iframe that a wireframe will be 51 * generated for. 52 * {Object} expectedWireframe 53 * An approximation of the wireframe that should be generated. The 54 * approximation is due to the fact that different platforms and 55 * execution environments might produce slightly different positioning 56 * of wireframe rects. We skip comparing the position of the rects, and 57 * only look at their dimensions (sometimes only one dimension if the 58 * other is potentially more variable - for example with text). Properties 59 * included in this object will do a strict comparison with the generated 60 * wireframe. Properties in the generated wireframe that are not in the 61 * expectedWireframe will be ignored. 62 */ 63 const kTests = [{ 64 // Base case: a simple solid background with a single character in the 65 // foreground. 66 html: ` 67 <html> 68 <style> 69 body { 70 width: 500px; 71 height: 500px; 72 background-color: ${RED_RGB}; 73 color: ${BLACK_RGB}; 74 overflow: hidden; 75 font-size: 12px; 76 } 77 </style> 78 <body>x</body> 79 </html> 80 `, 81 expectedWireframe: { 82 canvasBackground: RED_NSCOLOR, 83 rects: [{ 84 color: BLACK_NSCOLOR, 85 height: 12, 86 type: "text", 87 }] 88 }, 89 }, { 90 // Additional background on top of the main background. 91 html: ` 92 <html> 93 <style> 94 body { 95 background-color: ${RED_RGB}; 96 color: ${BLACK_RGB}; 97 overflow: hidden; 98 font-size: 12px; 99 } 100 div { 101 position: absolute; 102 top: 0; 103 left: 0; 104 width: 20px; 105 height: 20px; 106 background-color: ${GREEN_RGB}; 107 } 108 </style> 109 <body> 110 <div>x</div> 111 </body> 112 </html> 113 `, 114 expectedWireframe: { 115 canvasBackground: RED_NSCOLOR, 116 rects: [{ 117 color: GREEN_NSCOLOR, 118 height: 20, 119 width: 20, 120 type: "background", 121 }, { 122 color: BLACK_NSCOLOR, 123 height: 12, 124 type: "text", 125 }] 126 }, 127 }, { 128 // Image on top of the main background with another background 129 // floating in the top right. 130 html: ` 131 <html> 132 <style> 133 body { 134 background-color: ${RED_RGB}; 135 color: ${BLACK_RGB}; 136 overflow: hidden; 137 font-size: 12px; 138 } 139 div { 140 position: absolute; 141 top: 0; 142 right: 0; 143 width: 20px; 144 height: 20px; 145 background-color: ${GREEN_RGB}; 146 } 147 img { 148 position: absolute; 149 top: 0; 150 left: 0; 151 height: 50px; 152 width: 50px; 153 } 154 </style> 155 <body> 156 <img src="${TEST_PATH}/green.png"/> 157 <div>x</div> 158 </body> 159 </html> 160 `, 161 expectedWireframe: { 162 canvasBackground: RED_NSCOLOR, 163 rects: [{ 164 color: 0, 165 height: 50, 166 width: 50, 167 type: "image", 168 }, { 169 color: GREEN_NSCOLOR, 170 height: 20, 171 width: 20, 172 type: "background", 173 }, { 174 color: BLACK_NSCOLOR, 175 height: 12, 176 type: "text", 177 }] 178 }, 179 }, { 180 // Image on top of the main background with another background 181 // floating over the image 182 html: ` 183 <html> 184 <style> 185 body { 186 width: 500px; 187 height: 500px; 188 background-color: ${RED_RGB}; 189 color: ${BLACK_RGB}; 190 overflow: hidden; 191 font-size: 12px; 192 } 193 div { 194 position: absolute; 195 top: 0; 196 left: 0; 197 width: 20px; 198 height: 20px; 199 background-color: ${BLUE_RGB}; 200 } 201 img { 202 position: absolute; 203 top: 0; 204 left: 0; 205 height: 50px; 206 width: 50px; 207 } 208 </style> 209 <body> 210 <img src="${TEST_PATH}/green.png"/> 211 <div>x</div> 212 </body> 213 </html> 214 `, 215 expectedWireframe: { 216 canvasBackground: RED_NSCOLOR, 217 rects: [{ 218 color: 0, 219 height: 50, 220 width: 50, 221 type: "image", 222 }, { 223 color: BLUE_NSCOLOR, 224 height: 20, 225 width: 20, 226 type: "background", 227 }, { 228 color: BLACK_NSCOLOR, 229 height: 12, 230 type: "text", 231 }] 232 }, 233 }, { 234 // Bug 1759919 - Transformed items incorrectly causing us to not keep hit 235 // testing stuff. 236 html: ` 237 <!doctype html> 238 <style>:root { background-color: white; } body { margin: 0 }</style> 239 <div style="transform: rotate(90deg); width: 20px; height: 20px; overflow: clip;"> 240 <div style="width: 100%; height: 100%; background-color: blue;"></div> 241 </div> 242 <div style="transform: rotate(90deg); width: 20px; height: 20px; overflow: clip;"> 243 <div style="width: 100%; height: 100%; background-color: red;"></div> 244 </div> 245 `, 246 expectedWireframe: { 247 canvasBackground: WHITE_NSCOLOR, 248 rects: [{ 249 color: RED_NSCOLOR, 250 height: 20, 251 width: 20, 252 x: 0, 253 y: 0, 254 type: "background", 255 }, { 256 color: BLUE_NSCOLOR, 257 height: 20, 258 width: 20, 259 x: 0, 260 y: 20, 261 type: "background", 262 }], 263 } 264 }]; 265 266 /** 267 * Returns a Promise once page has been loaded in frame. 268 * 269 * @param {Element} frame 270 * The iframe to load the page in. 271 * @param {string} page 272 * The URL of the page to load in the frame. 273 * @returns {Promise<Event>} 274 * Resolves once the load event has fired for the frame. 275 */ 276 function loadInIframe(frame, page) { 277 return new Promise(resolve => { 278 frame.addEventListener("load", resolve, { once: true }); 279 frame.src = page; 280 }); 281 } 282 283 /** 284 * Compares a generated wireframe to an Object that contains some or all of 285 * the expected structure of the generated wireframe. 286 * 287 * If the wireframe doesn't contain the expected number of rects, the 288 * serialized structure of both the wireframe and approximateWireframe will 289 * be dumped to stdout. 290 * 291 * @param {Wireframe} wireframe 292 * A wireframe generated via document.getWireframe() 293 * @param {object} approximateWireframe 294 * An object that closely resembles a wireframe but the rects in the 295 * rects property do not need to contain all of the properties expected 296 * in a WireframeTaggedRect. Skipped properties won't be checked. 297 */ 298 function assertApproximateWireframe(wireframe, approximateWireframe) { 299 is( 300 wireframe.canvasBackground, 301 approximateWireframe.canvasBackground, 302 "Canvas backgrounds match." 303 ); 304 is( 305 wireframe.rects.length, 306 approximateWireframe.rects.length, 307 "Same rect count" 308 ); 309 if (wireframe.rects.length != approximateWireframe.rects.length) { 310 dump( 311 "Generated wireframe: " + JSON.stringify(wireframe, null, "\t") + "\n" 312 ); 313 dump( 314 "Expected approximate wireframe: " + 315 JSON.stringify(approximateWireframe, null, "\t") + 316 "\n" 317 ); 318 } 319 320 for (let index = 0; index < approximateWireframe.length; ++index) { 321 let wireframeRect = wireframe.rects[index]; 322 let approximationRect = approximateWireframe.rects[index]; 323 for (let prop of approximationRect) { 324 is( 325 wireframeRect[prop], 326 approximationRect[prop], 327 `Property ${prop} should be equal.` 328 ); 329 } 330 } 331 } 332 333 add_task(async () => { 334 const iframe = document.getElementById("iframe"); 335 336 for (let testDefinition of kTests) { 337 let pageURL = BUILDER + encodeURIComponent(testDefinition.html); 338 await loadInIframe(iframe, pageURL); 339 let wireframe = SpecialPowers.wrap( 340 iframe.contentDocument 341 ).getWireframe(); 342 assertApproximateWireframe(wireframe, testDefinition.expectedWireframe); 343 } 344 }); 345 </script> 346 </head> 347 <body> 348 <p id="display"></p> 349 <div id="content" style="display: none"></div> 350 <pre id="test"></pre> 351 <iframe id="iframe"></iframe> 352 </body> 353 </html>