test_visited_reftests.html (8825B)
1 <!DOCTYPE HTML> 2 <html> 3 <!-- 4 https://bugzilla.mozilla.org/show_bug.cgi?id=147777 5 --> 6 <head> 7 <title>Test for Bug 147777</title> 8 <script src="/tests/SimpleTest/SimpleTest.js"></script> 9 <script src="/tests/SimpleTest/WindowSnapshot.js"></script> 10 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> 11 </head> 12 <body> 13 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=147777">Mozilla Bug 147777</a> 14 <pre id="test"> 15 <script type="application/javascript"> 16 17 /** Test for Bug 147777 */ 18 19 // Because link-coloring for visited links is asynchronous, running 20 // reftests that involve link coloring requires that we poll for the 21 // correct result until all links are styled correctly. 22 23 // A requirement of these reftests is that the reference rendering is 24 // styled correctly when loaded. We only poll for the tests. 25 26 var gTests = [ 27 // there's also an implicit "load visited-page.html" at the start, 28 // thanks to the code below. 29 30 // IMPORTANT NOTE: For these tests, the test and reference are not 31 // snapshotted in the same way. The REFERENCE (second file) is 32 // assumed to be complete when loaded, but we poll for visited link 33 // coloring on the TEST (first file) until the test passes. 34 "== pseudo-classes-02.svg pseudo-classes-02-ref.svg", 35 "needs-focus == caret-color-on-visited-1.html caret-color-on-visited-1-ref.html", 36 "!= color-on-link-1-ref.html color-on-visited-1-ref.html", 37 "== color-on-link-1.html color-on-link-1-ref.html", 38 "== color-on-link-before-1.html color-on-link-1-ref.html", 39 "== color-on-visited-1.html color-on-visited-1-ref.html", 40 "== color-on-visited-before-1.html color-on-visited-1-ref.html", 41 "== color-on-visited-text-1.html color-on-visited-text-1-ref.html", 42 "!= content-color-on-link-before-1-ref.html content-color-on-visited-before-1-ref.html", 43 "== content-color-on-link-before-1.html content-color-on-link-before-1-ref.html", 44 "== content-color-on-visited-before-1.html content-color-on-visited-before-1-ref.html", 45 "== content-on-link-before-1.html content-before-1-ref.html", 46 "== content-on-visited-before-1.html content-before-1-ref.html", 47 "== color-on-text-decoration-1.html color-on-text-decoration-1-ref.html", 48 "== color-on-bullets-1.html color-on-bullets-1-ref.html", 49 // NOTE: background-color is tested by all the selector tests (and 50 // also color-choice-1) and therefore doesn't have its own tests. 51 // FIXME: Maybe add a test for selection colors (foreground and 52 // background), if possible. 53 "== width-on-link-1.html width-1-ref.html", 54 "== width-on-visited-1.html width-1-ref.html", 55 "== border-1.html border-1-ref.html", 56 "== border-2a.html border-2-ref.html", 57 "== border-2b.html border-2-ref.html", 58 // FIXME: Commented out because of dynamic change handling bugs in 59 // border-collapse tables that mean we get an incorrect rendering when 60 // the asynchronous restyle-from-history arrives. 61 //"== border-collapse-1.html border-collapse-1-ref.html", 62 "== outline-1.html outline-1-ref.html", 63 "== column-rule-1.html column-rule-1-ref.html", 64 "!= column-rule-1.html column-rule-1-notref.html", 65 "== color-choice-1.html color-choice-1-ref.html", 66 "== selector-descendant-1.html selector-descendant-1-ref.html", 67 "== selector-descendant-2.xhtml selector-descendant-2-ref.xhtml", 68 "== selector-child-1.html selector-child-1-ref.html", 69 "== selector-child-2.xhtml selector-child-2-ref.xhtml", 70 "== selector-adj-sibling-1.html selector-adj-sibling-1-ref.html", 71 "== selector-adj-sibling-2.html selector-adj-sibling-2-ref.html", 72 "== selector-adj-sibling-3.xhtml selector-adj-sibling-3-ref.xhtml", 73 "== selector-any-sibling-1.html selector-any-sibling-1-ref.html", 74 "== selector-any-sibling-2.html selector-any-sibling-2-ref.html", 75 "== subject-of-selector-descendant-1.html subject-of-selector-1-ref.html", 76 "== subject-of-selector-descendant-2.xhtml subject-of-selector-descendant-2-ref.xhtml", 77 "== subject-of-selector-child-1.html subject-of-selector-1-ref.html", 78 "== subject-of-selector-adj-sibling-1.html subject-of-selector-1-ref.html", 79 "== subject-of-selector-any-sibling-1.html subject-of-selector-1-ref.html", 80 "== inherit-keyword-1.xhtml inherit-keyword-1-ref.html", 81 "== svg-image-visited-1a.html svg-image-visited-1-ref.html", 82 "== svg-image-visited-1b.html svg-image-visited-1-ref.html", 83 "== svg-image-visited-1c.html svg-image-visited-1-ref.html", 84 "== svg-image-visited-1d.html svg-image-visited-1-ref.html", 85 // FIXME: commented out because dynamic changes on the non-first-line 86 // part of the test don't work right when the link becomes visited. 87 //"== first-line-1.html first-line-1-ref.html", 88 "== white-to-transparent-1.html white-to-transparent-1-ref.html", 89 "== link-root-1.xhtml link-root-1-ref.xhtml", 90 "== mathml-links.html mathml-links-ref.html", 91 "== placeholder-1.html placeholder-1-ref.html", 92 "== visited-inherit-1.html visited-inherit-1-ref.html", 93 "== transition-on-visited.html transition-on-visited-ref.html", 94 "== logical-box-border-color-visited-link-001.html logical-box-border-color-visited-link-ref.html", 95 "== logical-box-border-color-visited-link-002.html logical-box-border-color-visited-link-ref.html", 96 "== logical-box-border-color-visited-link-003.html logical-box-border-color-visited-link-ref.html", 97 "== svg-paint-currentcolor-visited.svg svg-paint-currentcolor-visited-ref.svg", 98 "== variables-visited.html variables-visited-ref.html", 99 ]; 100 101 // We record the maximum number of times we had to look at a test before 102 // it switched to the passing state (though we assume it's 10 to start 103 // rather than 0 so that we have a reasonable default). Then we make a 104 // test "time out" if it takes more than gTimeoutFactor times that 105 // amount of time. This allows us to report a test failure rather than 106 // making a test failure just show up as a timeout. 107 var gMaxPassingTries = 10; 108 var gTimeoutFactor = 10; 109 110 function startIframe(url) { 111 return new Promise(resolve => { 112 var element = document.createElement("iframe"); 113 element.addEventListener("load", () => { 114 element.contentDocument.fonts.ready.then(() => { 115 resolve(element.contentWindow); 116 }); 117 }, {once: true}); 118 // smaller than normal reftests, but enough for these 119 element.setAttribute("style", "width: 30em; height: 10em"); 120 element.src = "css-visited/" + url; 121 document.body.appendChild(element); 122 }); 123 } 124 125 async function runTests() { 126 SimpleTest.waitForExplicitFinish(); 127 SimpleTest.requestFlakyTimeout("async link coloring"); 128 // Set caret to a known size, for tests of :visited caret-color styling 129 await SpecialPowers.pushPrefEnv({'set': [['ui.caretWidth', 16]]}); 130 info("opening visited page"); 131 let win = window.open("css-visited/visited-page.html", "_blank"); 132 await new Promise(resolve => { 133 win.onload = resolve; 134 }); 135 info("running tests"); 136 await Promise.all(gTests.map(runTest)); 137 win.close(); 138 SimpleTest.finish(); 139 } 140 141 function passes(equal, shot1, shot2) 142 { 143 let [correct] = compareSnapshots(shot1, shot2, equal); 144 return correct; 145 } 146 147 function waitFor100msAndIdle() { 148 return new Promise(resolve => setTimeout(function() { 149 requestIdleCallback(resolve); 150 }, 100)); 151 } 152 153 async function runTest(testLine) { 154 let splitData = testLine.split(" "); 155 let isEqual; 156 let needsFocus = false; 157 while (true) { 158 let op = splitData.shift(); 159 if (op == "needs-focus") { 160 needsFocus = true; 161 } else if (op == "==" || op == "!=") { 162 isEqual = op == "=="; 163 break; 164 } else { 165 ok(false, "Unknown syntax"); 166 return; 167 } 168 } 169 let [testFile, refFile] = splitData; 170 171 let promiseTestWin = startIframe(testFile); 172 let promiseRefWin = startIframe(refFile); 173 let refSnapshot = snapshotWindow(await promiseRefWin); 174 let testWindow = await promiseTestWin; 175 // Always wait at least 100ms, so that any test that switches 176 // from passing to failing when the asynchronous link coloring 177 // happens should fail at least some of the time. 178 await waitFor100msAndIdle(); 179 180 let tries; 181 let testSnapshot; 182 for (tries = 0; tries < gMaxPassingTries * gTimeoutFactor; ++tries) { 183 if (needsFocus) { 184 await SimpleTest.promiseFocus(testWindow, false); 185 } 186 testSnapshot = snapshotWindow(testWindow, true); 187 if (passes(isEqual, testSnapshot, refSnapshot)) { 188 if (tries > gMaxPassingTries) { 189 gMaxPassingTries = tries; 190 } 191 break; 192 } 193 // Links might not have been colored yet. Try again in 100ms. 194 await waitFor100msAndIdle(); 195 } 196 197 let result = assertSnapshots(testSnapshot, refSnapshot, 198 isEqual, null, testFile, refFile); 199 if (!result) { 200 info(`Gave up after ${tries} tries, ` + 201 `maxp=${gMaxPassingTries}, fact=${gTimeoutFactor}`); 202 } 203 } 204 205 runTests(); 206 207 </script> 208 </pre> 209 </body> 210 </html>