<!
DOCTYPE HTML>
<
html>
<
head>
<
meta charset=
"utf-8">
<
title>Tests for document.getWireframe()</
title>
<
script src=
"/tests/SimpleTest/SimpleTest.js"></
script>
<
link rel=
"stylesheet" href=
"/tests/SimpleTest/test.css"/>
<
script>
/**
* This test creates some simple webpages, captures wireframes for them, and
* then compares them against some expected wireframe structures.
*/
/**
* Converts some RGB values into the same uint32_t nsColor representation
* that getWireframe uses.
*
* @
param {number} r
* Red color value.
* @
param {number} g
* Green color value.
* @
param {number}
b
* Blue color value.
* @returns {number}
* The red, green and blue values composed in
a single uint32_t-compatible
* value.
*/
function nscolor(r, g,
b) {
return (
255 <<
24 |
b <<
16 | g <<
8 | r) >>>
0;
}
const WHITE_NSCOLOR = nscolor(
255,
255,
255);
const RED_RGB =
"rgb(255, 0, 0)";
const RED_NSCOLOR = nscolor(
255,
0,
0);
const GREEN_RGB =
"rgb(0, 255, 0)";
const GREEN_NSCOLOR = nscolor(
0,
255,
0);
const BLUE_RGB =
"rgb(0, 0, 255)";
const BLUE_NSCOLOR = nscolor(
0,
0,
255);
const BLACK_RGB =
"rgb(0, 0, 0)";
const BLACK_NSCOLOR = nscolor(
0,
0,
0);
const BUILDER =
"http://mochi.test:8888/document-builder.sjs?html=";
const TEST_PATH =
"http://mochi.test:8888/tests/dom/base/test/";
/**
* This array contains the definition of each test. Each test is an
object
* that expects two properties:
*
* {String}
html
* The markup to be loaded in the page
iframe that
a wireframe will be
* generated for.
* {
Object} expectedWireframe
* An approximation of the wireframe that should be generated. The
* approximation is due to the fact that different platforms and
* execution environments might produce slightly different positioning
* of wireframe rects. We skip comparing the position of the rects, and
* only look at their dimensions (sometimes only one dimension if the
* other is potentially more variable - for example with text). Properties
* included in this
object will do
a strict comparison with the generated
* wireframe. Properties in the generated wireframe that are not in the
* expectedWireframe will be ignored.
*/
const kTests = [{
//
Base case:
a simple solid background with
a single character in the
// foreground.
html: `
<
html>
<
style>
body {
width:
500px;
height:
500px;
background-color: ${RED_RGB};
color: ${BLACK_RGB};
overflow: hidden;
font-size:
12px;
}
</
style>
<
body>x</
body>
</
html>
`,
expectedWireframe: {
canvasBackground: RED_NSCOLOR,
rects: [{
color: BLACK_NSCOLOR,
height:
12,
type:
"text",
}]
},
}, {
// Additional background on top of the main background.
html: `
<
html>
<
style>
body {
background-color: ${RED_RGB};
color: ${BLACK_RGB};
overflow: hidden;
font-size:
12px;
}
div {
position: absolute;
top:
0;
left:
0;
width:
20px;
height:
20px;
background-color: ${GREEN_RGB};
}
</
style>
<
body>
<
div>x</
div>
</
body>
</
html>
`,
expectedWireframe: {
canvasBackground: RED_NSCOLOR,
rects: [{
color: GREEN_NSCOLOR,
height:
20,
width:
20,
type:
"background",
}, {
color: BLACK_NSCOLOR,
height:
12,
type:
"text",
}]
},
}, {
// Image on top of the main background with another background
// floating in the top right.
html: `
<
html>
<
style>
body {
background-color: ${RED_RGB};
color: ${BLACK_RGB};
overflow: hidden;
font-size:
12px;
}
div {
position: absolute;
top:
0;
right:
0;
width:
20px;
height:
20px;
background-color: ${GREEN_RGB};
}
img {
position: absolute;
top:
0;
left:
0;
height:
50px;
width:
50px;
}
</
style>
<
body>
<
img src=
"${TEST_PATH}/green.png"/>
<
div>x</
div>
</
body>
</
html>
`,
expectedWireframe: {
canvasBackground: RED_NSCOLOR,
rects: [{
color:
0,
height:
50,
width:
50,
type:
"image",
}, {
color: GREEN_NSCOLOR,
height:
20,
width:
20,
type:
"background",
}, {
color: BLACK_NSCOLOR,
height:
12,
type:
"text",
}]
},
}, {
// Image on top of the main background with another background
// floating over the image
html: `
<
html>
<
style>
body {
width:
500px;
height:
500px;
background-color: ${RED_RGB};
color: ${BLACK_RGB};
overflow: hidden;
font-size:
12px;
}
div {
position: absolute;
top:
0;
left:
0;
width:
20px;
height:
20px;
background-color: ${BLUE_RGB};
}
img {
position: absolute;
top:
0;
left:
0;
height:
50px;
width:
50px;
}
</
style>
<
body>
<
img src=
"${TEST_PATH}/green.png"/>
<
div>x</
div>
</
body>
</
html>
`,
expectedWireframe: {
canvasBackground: RED_NSCOLOR,
rects: [{
color:
0,
height:
50,
width:
50,
type:
"image",
}, {
color: BLUE_NSCOLOR,
height:
20,
width:
20,
type:
"background",
}, {
color: BLACK_NSCOLOR,
height:
12,
type:
"text",
}]
},
}, {
// Bug
1759919 - Transformed items incorrectly causing us to not keep hit
// testing stuff.
html: `
<!
doctype html>
<
style>:root { background-color: white; }
body { margin:
0 }</
style>
<
div style=
"transform: rotate(90deg); width: 20px; height: 20px; overflow: clip;">
<
div style=
"width: 100%; height: 100%; background-color: blue;"></
div>
</
div>
<
div style=
"transform: rotate(90deg); width: 20px; height: 20px; overflow: clip;">
<
div style=
"width: 100%; height: 100%; background-color: red;"></
div>
</
div>
`,
expectedWireframe: {
canvasBackground: WHITE_NSCOLOR,
rects: [{
color: RED_NSCOLOR,
height:
20,
width:
20,
x:
0,
y:
0,
type:
"background",
}, {
color: BLUE_NSCOLOR,
height:
20,
width:
20,
x:
0,
y:
20,
type:
"background",
}],
}
}];
/**
* Returns
a Promise once page has been loaded in
frame.
*
* @
param {Element}
frame
* The
iframe to load the page in.
* @
param {string} page
* The URL of the page to load in the
frame.
* @returns {Promise<Event>}
* Resolves once the load event has fired for the
frame.
*/
function loadInIframe(
frame, page) {
return new Promise(resolve => {
frame.addEventListener(
"load", resolve, { once: true });
frame.src = page;
});
}
/**
* Compares
a generated wireframe to an
Object that contains some or all of
* the expected structure of the generated wireframe.
*
* If the wireframe doesn
't contain the expected number of rects, the
* serialized structure of both the wireframe and approximateWireframe will
* be dumped to stdout.
*
* @
param {Wireframe} wireframe
*
A wireframe generated via document.getWireframe()
* @
param {
object} approximateWireframe
* An
object that closely resembles
a wireframe but the rects in the
* rects property do not need to contain all of the properties expected
* in
a WireframeTaggedRect. Skipped properties won
't be checked.
*/
function assertApproximateWireframe(wireframe, approximateWireframe) {
is(
wireframe.canvasBackground,
approximateWireframe.canvasBackground,
"Canvas backgrounds match."
);
is(
wireframe.rects.length,
approximateWireframe.rects.length,
"Same rect count"
);
if (wireframe.rects.length != approximateWireframe.rects.length) {
dump(
"Generated wireframe: " + JSON.stringify(wireframe, null,
"\t") +
"\n"
);
dump(
"Expected approximate wireframe: " +
JSON.stringify(approximateWireframe, null,
"\t") +
"\n"
);
}
for (let index =
0; index < approximateWireframe.length; ++index) {
let wireframeRect = wireframe.rects[index];
let approximationRect = approximateWireframe.rects[index];
for (let prop of approximationRect) {
is(
wireframeRect[prop],
approximationRect[prop],
`Property ${prop} should be equal.`
);
}
}
}
add_task(async () => {
const
iframe = document.getElementById(
"iframe");
for (let testDefinition of kTests) {
let pageURL = BUILDER + encodeURIComponent(testDefinition.
html);
await loadInIframe(
iframe, pageURL);
let wireframe = SpecialPowers.wrap(
iframe.contentDocument
).getWireframe();
assertApproximateWireframe(wireframe, testDefinition.expectedWireframe);
}
});
</
script>
</
head>
<
body>
<
p id=
"display"></
p>
<
div id=
"content" style=
"display: none"></
div>
<
pre id=
"test"></
pre>
<
iframe id=
"iframe"></
iframe>
</
body>
</
html>