2 testRunner.dumpAsText();
6 function insertAfter(nodeToAdd, referenceNode)
8 if (referenceNode == document.body) {
9 document.body.appendChild(nodeToAdd);
13 if (referenceNode.nextSibling)
14 referenceNode.parentNode.insertBefore(nodeToAdd, referenceNode.nextSibling);
16 referenceNode.parentNode.appendChild(nodeToAdd);
19 function checkSubtreeExpectedValues(parent, failures)
21 var checkedLayout = checkExpectedValues(parent, failures);
22 Array.prototype.forEach.call(parent.childNodes, function(node) {
23 checkedLayout |= checkSubtreeExpectedValues(node, failures);
28 function checkAttribute(output, node, attribute)
30 var result = node.getAttribute && node.getAttribute(attribute);
31 output.checked |= !!result;
35 function checkExpectedValues(node, failures)
37 var output = { checked: false };
38 var expectedWidth = checkAttribute(output, node, "data-expected-width");
40 if (node.offsetWidth != parseInt(expectedWidth))
41 failures.push("Expected " + expectedWidth + " for width, but got " + node.offsetWidth + ". ");
44 var expectedHeight = checkAttribute(output, node, "data-expected-height");
46 if (node.offsetHeight != parseInt(expectedHeight))
47 failures.push("Expected " + expectedHeight + " for height, but got " + node.offsetHeight + ". ");
50 var expectedOffset = checkAttribute(output, node, "data-offset-x");
52 if (node.offsetLeft != parseInt(expectedOffset))
53 failures.push("Expected " + expectedOffset + " for offsetLeft, but got " + node.offsetLeft + ". ");
56 var expectedOffset = checkAttribute(output, node, "data-offset-y");
58 if (node.offsetTop != parseInt(expectedOffset))
59 failures.push("Expected " + expectedOffset + " for offsetTop, but got " + node.offsetTop + ". ");
62 var expectedWidth = checkAttribute(output, node, "data-expected-client-width");
64 if (node.clientWidth != parseInt(expectedWidth))
65 failures.push("Expected " + expectedWidth + " for clientWidth, but got " + node.clientWidth + ". ");
68 var expectedHeight = checkAttribute(output, node, "data-expected-client-height");
70 if (node.clientHeight != parseInt(expectedHeight))
71 failures.push("Expected " + expectedHeight + " for clientHeight, but got " + node.clientHeight + ". ");
74 var expectedWidth = checkAttribute(output, node, "data-expected-scroll-width");
76 if (node.scrollWidth != parseInt(expectedWidth))
77 failures.push("Expected " + expectedWidth + " for scrollWidth, but got " + node.scrollWidth + ". ");
80 var expectedHeight = checkAttribute(output, node, "data-expected-scroll-height");
82 if (node.scrollHeight != parseInt(expectedHeight))
83 failures.push("Expected " + expectedHeight + " for scrollHeight, but got " + node.scrollHeight + ". ");
86 var expectedOffset = checkAttribute(output, node, "data-total-x");
88 var totalLeft = node.clientLeft + node.offsetLeft;
89 if (totalLeft != parseInt(expectedOffset))
90 failures.push("Expected " + expectedOffset + " for clientLeft+offsetLeft, but got " + totalLeft + ", clientLeft: " + node.clientLeft + ", offsetLeft: " + node.offsetLeft + ". ");
93 var expectedOffset = checkAttribute(output, node, "data-total-y");
95 var totalTop = node.clientTop + node.offsetTop;
96 if (totalTop != parseInt(expectedOffset))
97 failures.push("Expected " + expectedOffset + " for clientTop+offsetTop, but got " + totalTop + ", clientTop: " + node.clientTop + ", + offsetTop: " + node.offsetTop + ". ");
100 var expectedDisplay = checkAttribute(output, node, "data-expected-display");
101 if (expectedDisplay) {
102 var actualDisplay = getComputedStyle(node).display;
103 if (actualDisplay != expectedDisplay)
104 failures.push("Expected " + expectedDisplay + " for display, but got " + actualDisplay + ". ");
107 var expectedPaddingTop = checkAttribute(output, node, "data-expected-padding-top");
108 if (expectedPaddingTop) {
109 var actualPaddingTop = getComputedStyle(node).paddingTop;
110 // Trim the unit "px" from the output.
111 actualPaddingTop = actualPaddingTop.substring(0, actualPaddingTop.length - 2);
112 if (actualPaddingTop != expectedPaddingTop)
113 failures.push("Expected " + expectedPaddingTop + " for padding-top, but got " + actualPaddingTop + ". ");
116 var expectedPaddingBottom = checkAttribute(output, node, "data-expected-padding-bottom");
117 if (expectedPaddingBottom) {
118 var actualPaddingBottom = getComputedStyle(node).paddingBottom;
119 // Trim the unit "px" from the output.
120 actualPaddingBottom = actualPaddingBottom.substring(0, actualPaddingBottom.length - 2);
121 if (actualPaddingBottom != expectedPaddingBottom)
122 failures.push("Expected " + expectedPaddingBottom + " for padding-bottom, but got " + actualPaddingBottom + ". ");
125 var expectedPaddingLeft = checkAttribute(output, node, "data-expected-padding-left");
126 if (expectedPaddingLeft) {
127 var actualPaddingLeft = getComputedStyle(node).paddingLeft;
128 // Trim the unit "px" from the output.
129 actualPaddingLeft = actualPaddingLeft.substring(0, actualPaddingLeft.length - 2);
130 if (actualPaddingLeft != expectedPaddingLeft)
131 failures.push("Expected " + expectedPaddingLeft + " for padding-left, but got " + actualPaddingLeft + ". ");
134 var expectedPaddingRight = checkAttribute(output, node, "data-expected-padding-right");
135 if (expectedPaddingRight) {
136 var actualPaddingRight = getComputedStyle(node).paddingRight;
137 // Trim the unit "px" from the output.
138 actualPaddingRight = actualPaddingRight.substring(0, actualPaddingRight.length - 2);
139 if (actualPaddingRight != expectedPaddingRight)
140 failures.push("Expected " + expectedPaddingRight + " for padding-right, but got " + actualPaddingRight + ". ");
143 var expectedMarginTop = checkAttribute(output, node, "data-expected-margin-top");
144 if (expectedMarginTop) {
145 var actualMarginTop = getComputedStyle(node).marginTop;
146 // Trim the unit "px" from the output.
147 actualMarginTop = actualMarginTop.substring(0, actualMarginTop.length - 2);
148 if (actualMarginTop != expectedMarginTop)
149 failures.push("Expected " + expectedMarginTop + " for margin-top, but got " + actualMarginTop + ". ");
152 var expectedMarginBottom = checkAttribute(output, node, "data-expected-margin-bottom");
153 if (expectedMarginBottom) {
154 var actualMarginBottom = getComputedStyle(node).marginBottom;
155 // Trim the unit "px" from the output.
156 actualMarginBottom = actualMarginBottom.substring(0, actualMarginBottom.length - 2);
157 if (actualMarginBottom != expectedMarginBottom)
158 failures.push("Expected " + expectedMarginBottom + " for margin-bottom, but got " + actualMarginBottom + ". ");
161 var expectedMarginLeft = checkAttribute(output, node, "data-expected-margin-left");
162 if (expectedMarginLeft) {
163 var actualMarginLeft = getComputedStyle(node).marginLeft;
164 // Trim the unit "px" from the output.
165 actualMarginLeft = actualMarginLeft.substring(0, actualMarginLeft.length - 2);
166 if (actualMarginLeft != expectedMarginLeft)
167 failures.push("Expected " + expectedMarginLeft + " for margin-left, but got " + actualMarginLeft + ". ");
170 var expectedMarginRight = checkAttribute(output, node, "data-expected-margin-right");
171 if (expectedMarginRight) {
172 var actualMarginRight = getComputedStyle(node).marginRight;
173 // Trim the unit "px" from the output.
174 actualMarginRight = actualMarginRight.substring(0, actualMarginRight.length - 2);
175 if (actualMarginRight != expectedMarginRight)
176 failures.push("Expected " + expectedMarginRight + " for margin-right, but got " + actualMarginRight + ". ");
179 return output.checked;
182 window.checkLayout = function(selectorList, overrideContainer)
185 console.error("You must provide a CSS selector of nodes to check.");
188 var nodes = document.querySelectorAll(selectorList);
189 nodes = Array.prototype.slice.call(nodes);
191 var checkedLayout = false;
192 Array.prototype.forEach.call(nodes, function(node) {
194 checkedLayout |= checkExpectedValues(node.parentNode, failures);
195 checkedLayout |= checkSubtreeExpectedValues(node, failures);
197 var container = overrideContainer || (node.parentNode.className == 'container' ? node.parentNode : node);
199 var pre = document.createElement('pre');
201 pre.className = 'FAIL';
202 pre.appendChild(document.createTextNode(failures.length ? "FAIL:\n" + failures.join('\n') + '\n\n' + container.outerHTML : "PASS"));
203 insertAfter(pre, container);
206 if (!checkedLayout) {
207 document.body.innerHTML = "FAIL: No valid data-* attributes found in selector list : " + selectorList;
211 var pre = document.querySelector('.FAIL');
213 setTimeout(function() { pre.previousSibling.scrollIntoView(); }, 0);