tizen beta release
[framework/web/webkit-efl.git] / LayoutTests / fast / harness / resources / results-test.js
1 // To run these tests, load json_results.html in a browser.
2 // You should see a series of PASS lines.
3 if (window.layoutTestController)
4     layoutTestController.dumpAsText();
5
6 var testStyles = document.createElement('style');
7 testStyles.innerText = ".test-pass { color: green; } .test-fail { color: red; }";
8 document.querySelector('head').appendChild(testStyles);
9
10 var g_testIndex = 0;
11 var g_log = ["You should see a serios of PASS lines."];
12
13 // Make async actually be sync for the sake of simpler testing.
14 function async(func, args)
15 {
16     func.apply(null, args);
17 }
18
19 function mockResults()
20 {
21     return {
22         tests: {},
23         "skipped": 0,
24         "num_regressions": 0,
25         "version": 0,
26         "num_passes": 0,
27         "fixable": 0,
28         "num_flaky": 0,
29         "layout_tests_dir": "/WEBKITROOT",
30         "uses_expectations_file": true,
31         "has_pretty_patch": false,
32         "has_wdiff": false,
33         "revision": 12345
34     };
35 }
36
37 function mockExpectation(expected, actual, diff_percentage)
38 {
39     diff_percentage = (typeof(diff_percentage) == undefined) ? 0 : diff_percentage;
40     return {
41         expected: expected,
42         time_ms: 1,
43         actual: actual,
44         image_diff_percent: diff_percentage,
45         has_stderr: false
46     };
47 }
48
49 function logPass(msg)
50 {
51     g_log.push('TEST-' + g_testIndex + ': <span class="test-pass">' + msg + '</span>')
52 }
53
54 function logFail(msg)
55 {
56     g_log.push('TEST-' + g_testIndex + ': <span class="test-fail">' + msg + '</span>')
57 }
58
59 function assertTrue(bool)
60 {
61     if (bool)
62         logPass('PASS');
63     else
64         logFail('FAIL');
65 }
66
67 function runTest(results, assertions, opt_localStorageValue)
68 {
69     document.body.innerHTML = '';
70     g_testIndex++;
71     g_state = undefined;
72     localStorage.setItem(OptionWriter._key, opt_localStorageValue || '');
73
74     try {
75         ADD_RESULTS(results);
76         originalGeneratePage();
77     } catch (e) {
78         logFail("FAIL: uncaught exception " + e.toString());
79     }
80     
81     try {
82         assertions();
83     } catch (e) {
84         logFail("FAIL: uncaught exception executing assertions " + e.toString());
85     }
86 }
87
88 function runDefaultSingleRowTest(test, expected, actual, diff_percentage, isExpected, textResults, imageResults)
89 {
90     results = mockResults();
91     results.tests[test] = mockExpectation(expected, actual, diff_percentage);
92     runSingleRowTest(results, isExpected, textResults, imageResults);
93 }
94
95 function runSingleRowTest(results, isExpected, textResults, imageResults)
96 {
97     for (var key in results.tests)
98         var test = key;
99     var expected = results.tests[test].expected;
100     var actual = results.tests[test].actual;
101     runTest(results, function() {
102         if (isExpected)
103             assertTrue(document.querySelector('tbody').className == 'expected');
104         else
105             assertTrue(document.querySelector('tbody').className.indexOf('expected') == -1);
106
107         assertTrue(document.querySelector('tbody td:nth-child(1)').textContent == '+' + test);
108         assertTrue(document.querySelector('tbody td:nth-child(2)').textContent == textResults);
109         assertTrue(document.querySelector('tbody td:nth-child(3)').textContent == imageResults);
110         assertTrue(document.querySelector('tbody td:nth-child(4)').textContent == actual);
111         assertTrue(document.querySelector('tbody td:nth-child(5)').textContent == expected);
112     });
113     
114 }
115
116 function runTests()
117 {
118     var results = mockResults();
119     var subtree = results.tests['foo'] = {}
120     subtree['bar.html'] = mockExpectation('PASS', 'TEXT');
121     runTest(results, function() {
122         assertTrue(document.getElementById('image-results-header').textContent == '');
123         assertTrue(document.getElementById('text-results-header').textContent != '');
124         
125         var optionsMenu = document.getElementById('options-menu');
126         assertTrue(window.getComputedStyle(optionsMenu, null)['opacity'] == 0)
127         toggleOptionsMenu();
128         toggleOptionsMenu();
129         // FIXME: Test the opacity after toggling the menu.
130         // Can't just do it inline due to CSS transitions.
131     });
132
133     results = mockResults();
134     var subtree = results.tests['foo'] = {}
135     subtree['bar.html'] = mockExpectation('TEXT', 'MISSING');
136     subtree['bar.html'].is_missing_text = true;
137     subtree['bar.html'].is_missing_audio = true;
138     subtree['bar.html'].is_missing_image = true;
139     runTest(results, function() {
140         assertTrue(!document.getElementById('results-table'));
141         assertTrue(document.querySelector('#missing-table .test-link').textContent == 'foo/bar.html');
142         assertTrue(document.getElementsByClassName('result-link')[0].textContent == 'audio result');
143         assertTrue(document.getElementsByClassName('result-link')[1].textContent == 'result');
144         assertTrue(document.getElementsByClassName('result-link')[2].textContent == 'png result');
145     });
146
147     results = mockResults();
148     var subtree = results.tests['foo'] = {}
149     subtree['bar.html'] = mockExpectation('PASS', 'TEXT');
150     subtree['bar.html'].has_stderr = true;
151     runTest(results, function() {
152         assertTrue(document.getElementById('results-table'));
153         assertTrue(document.querySelector('#stderr-table .result-link').textContent == 'stderr');
154     });
155
156     results = mockResults();
157     var subtree = results.tests['foo'] = {}
158     subtree['bar.html'] = mockExpectation('TEXT', 'PASS');
159     subtree['bar1.html'] = mockExpectation('CRASH', 'PASS');
160     subtree['bar2.html'] = mockExpectation('IMAGE', 'PASS');
161     subtree['crash.html'] = mockExpectation('IMAGE', 'CRASH');
162     subtree['timeout.html'] = mockExpectation('IMAGE', 'TIMEOUT');
163     runTest(results, function() {
164         assertTrue(!document.getElementById('results-table'));
165
166         var testLinks = document.querySelectorAll('#passes-table .test-link');
167         assertTrue(testLinks[0].textContent == 'foo/bar.html');
168         assertTrue(testLinks[1].textContent == 'foo/bar1.html');
169         assertTrue(testLinks[2].textContent == 'foo/bar2.html');
170         
171         assertTrue(!document.querySelector('#passes-table .expand-button'));
172
173         var expectationTypes = document.querySelectorAll('#passes-table td:last-of-type');
174         assertTrue(expectationTypes[0].textContent == 'TEXT');
175         assertTrue(expectationTypes[1].textContent == 'CRASH');
176         assertTrue(expectationTypes[2].textContent == 'IMAGE');
177         
178         assertTrue(document.getElementById('crash-tests-table'));
179         assertTrue(document.getElementById('crash-tests-table').textContent.indexOf('crash log') != -1);
180         assertTrue(document.getElementById('timeout-tests-table'));
181         assertTrue(document.getElementById('timeout-tests-table').textContent.indexOf('expected actual diff') != -1);
182     });
183
184     results = mockResults();
185     var subtree = results.tests['foo'] = {}
186     subtree['bar.html'] = mockExpectation('TEXT', 'PASS');
187     subtree['bar-missing.html'] = mockExpectation('TEXT', 'MISSING');
188     subtree['bar-missing.html'].is_missing_text = true;
189     subtree['bar-stderr.html'] = mockExpectation('PASS', 'TEXT');
190     subtree['bar-stderr.html'].has_stderr = true;
191     subtree['bar-unexpected-pass.html'] = mockExpectation('TEXT', 'PASS');
192     runTest(results, function() {
193         assertTrue(document.querySelectorAll('tbody tr').length == 5);
194         expandAllExpectations();
195         assertTrue(document.querySelectorAll('tbody tr').length == 8);
196         var expandLinks = document.querySelectorAll('.expand-button-text');
197         var enDash = '\u2013';
198         for (var i = 0; i < expandLinks.length; i++) {
199             assertTrue(expandLinks[i].textContent == enDash);
200         }
201         
202         collapseAllExpectations();
203         // Collapsed expectations stay in the dom, but are display:none.
204         assertTrue(document.querySelectorAll('tbody tr').length == 8);
205         var expandLinks = document.querySelectorAll('.expand-button-text');
206         for (var i = 0; i < expandLinks.length; i++)
207             assertTrue(expandLinks[i].textContent == '+');
208             
209         expandExpectations(expandLinks[1]);
210         assertTrue(expandLinks[0].textContent == '+');
211         assertTrue(expandLinks[1].textContent == enDash);
212
213         collapseExpectations(expandLinks[1]);
214         assertTrue(expandLinks[1].textContent == '+');
215     });
216
217     results = mockResults();
218     var subtree = results.tests['foo'] = {}
219     subtree['bar.html'] = mockExpectation('PASS', 'TEXT');
220     subtree['bar-expected-fail.html'] = mockExpectation('TEXT', 'TEXT');
221     runTest(results, function() {
222         assertTrue(document.querySelectorAll('.expected').length == 1);
223         assertTrue(document.querySelector('.expected .test-link').textContent == 'foo/bar-expected-fail.html');
224
225         assertTrue(window.getComputedStyle(document.querySelectorAll('tbody')[0], null)['display'] == 'none');
226
227         expandAllExpectations();
228         assertTrue(visibleExpandLinks().length == 1);
229         assertTrue(document.querySelectorAll('.results-row').length == 1);
230         assertTrue(window.getComputedStyle(document.querySelectorAll('tbody')[0], null)['display'] == 'none');
231         
232         document.getElementById('unexpected-results').checked = false;
233         document.getElementById('unexpected-results').onchange();
234
235         assertTrue(visibleExpandLinks().length == 2);
236         assertTrue(document.querySelectorAll('.results-row').length == 1);
237         assertTrue(window.getComputedStyle(document.querySelectorAll('tbody')[0], null)['display'] != 'none');
238         
239         expandAllExpectations();
240         assertTrue(document.querySelectorAll('.results-row').length == 2);
241         assertTrue(window.getComputedStyle(document.querySelectorAll('tbody')[0], null)['display'] != 'none');
242     });
243     
244     results = mockResults();
245     results.tests['only-expected-fail.html'] = mockExpectation('TEXT', 'TEXT');
246     runTest(results, function() {
247         assertTrue(window.getComputedStyle(document.getElementById('results-table').parentNode, null)['display'] == 'none');
248     });
249
250     runDefaultSingleRowTest('bar-skip.html', 'TEXT', 'SKIP', 0, true, '', '');
251     runDefaultSingleRowTest('bar-flaky-fail.html', 'PASS FAIL', 'TEXT', 0, true, 'expected actual diff ', '');
252     runDefaultSingleRowTest('bar-flaky-fail-unexpected.html', 'PASS TEXT', 'IMAGE', 1, false, '', 'images diff (1%) ');
253     runDefaultSingleRowTest('bar-audio.html', 'TEXT', 'AUDIO', 0, false, 'expected audio actual audio ', '');
254     runDefaultSingleRowTest('bar-image.html', 'TEXT', 'IMAGE', 1, false, '', 'images diff (1%) ');
255     runDefaultSingleRowTest('bar-image-plus-text.html', 'TEXT', 'IMAGE+TEXT', 1, false, 'expected actual diff ', 'images diff (1%) ');
256
257     results = mockResults();
258     results.tests['bar-reftest.html'] = mockExpectation('PASS', 'IMAGE', 1);
259     results.tests['bar-reftest.html'].is_reftest = true;
260     runSingleRowTest(results, false, '', 'ref html images diff (1%) ');
261
262     results = mockResults();
263     results.tests['bar-reftest-mismatch.html'] = mockExpectation('PASS', 'IMAGE');
264     results.tests['bar-reftest-mismatch.html'].is_mismatch_reftest = true;
265     runSingleRowTest(results, false, '', 'ref mismatch html actual ');
266
267     results = mockResults();
268     results.tests['bar-reftest.html'] = mockExpectation('PASS', 'IMAGE', 1);
269     results.tests['bar-reftest.html'].is_reftest = true;
270     results.tests['bar-reftest.html'].ref_file = 'common.html';
271     runSingleRowTest(results, false, '', 'ref html images diff (1%) ');
272     runTest(results, function() {
273         assertTrue(document.getElementsByClassName('result-link')[0].getAttribute('href') == 'common.html');
274     });
275
276     results = mockResults();
277     results.tests['bar-reftest.html'] = mockExpectation('PASS', 'IMAGE');
278     results.tests['bar-reftest.html'].is_mismatch_reftest = true;
279     results.tests['bar-reftest.html'].ref_file = 'common.html';
280     runSingleRowTest(results, false, '', 'ref mismatch html actual ');
281     runTest(results, function() {
282         assertTrue(document.getElementsByClassName('result-link')[0].getAttribute('href') == 'common.html');
283     });
284
285     results = mockResults();
286     var subtree = results.tests['foo'] = {}
287     subtree['bar-flaky-pass.html'] = mockExpectation('PASS TEXT', 'PASS');
288     runTest(results, function() {
289         assertTrue(!document.getElementById('results-table'));
290         assertTrue(document.getElementById('passes-table'));
291         assertTrue(document.body.textContent.indexOf('foo/bar-flaky-pass.html') != -1);
292     });
293
294     results = mockResults();
295     var subtree = results.tests['foo'] = {}
296     subtree['bar-flaky-fail.html'] = mockExpectation('PASS TEXT', 'IMAGE PASS');
297     runTest(results, function() {
298         assertTrue(!document.getElementById('results-table'));
299         assertTrue(document.getElementById('flaky-tests-table'));
300         assertTrue(document.body.textContent.indexOf('bar-flaky-fail.html') != -1);
301     });
302
303     results = mockResults();
304     var subtree = results.tests['foo'] = {}
305     subtree['bar-flaky-expected.html'] = mockExpectation('PASS FAIL', 'PASS TEXT');
306     runTest(results, function() {
307         assertTrue(!document.getElementById('results-table'));
308         assertTrue(document.getElementById('flaky-tests-table'));
309         assertTrue(document.body.textContent.indexOf('bar-flaky-expected.html') != -1);
310         assertTrue(document.querySelector('tbody').className == 'expected');
311     });
312
313     results = mockResults();
314     var subtree = results.tests['foo'] = {}
315     subtree['bar-really-long-path-that-should-probably-wrap-because-otherwise-the-table-will-be-too-wide.html'] = mockExpectation('PASS', 'TEXT');
316     runTest(results, function() {
317         document.body.style.width = '800px';
318         var links = document.querySelectorAll('tbody a');
319         assertTrue(links[0].getClientRects().length == 2);
320         assertTrue(links[1].getClientRects().length == 1);
321         document.body.style.width = '';
322     });
323
324     results = mockResults();
325     var subtree = results.tests['foo'] = {}
326     subtree['bar.html'] = mockExpectation('TEXT', 'TEXT');
327     subtree['bar1.html'] = mockExpectation('CRASH', 'PASS');
328     subtree['bar2.html'] = mockExpectation('IMAGE', 'PASS');
329     subtree['flaky-fail.html'] = mockExpectation('PASS TEXT', 'IMAGE PASS');
330     results.uses_expectations_file = false;
331     runTest(results, function() {
332         assertTrue(window.getComputedStyle(document.getElementById('results-table').parentNode, null)['display'] != 'none');
333         assertTrue(document.querySelectorAll('#results-table tbody td').length == 3);
334         assertTrue(!document.querySelector('tbody.expected'));
335         assertTrue(!document.getElementById('passes-table'));
336         assertTrue(document.querySelectorAll('#flaky-tests-table tbody td').length == 4);
337     });
338
339     results = mockResults();
340     var subtree = results.tests['foo'] = {}
341     subtree['bar.html'] = mockExpectation('TEXT', 'TEXT');
342     results.has_pretty_patch = true;
343     runTest(results, function() {
344         assertTrue(document.querySelector('tbody td:nth-child(2)').textContent.indexOf('pretty diff') != -1);
345         assertTrue(document.querySelector('tbody td:nth-child(2)').textContent.indexOf('wdiff') == -1);
346     });
347
348     results = mockResults();
349     var subtree = results.tests['foo'] = {}
350     subtree['bar.html'] = mockExpectation('TEXT', 'TEXT');
351     results.has_wdiff = true;
352     runTest(results, function() {
353         assertTrue(document.querySelector('tbody td:nth-child(2)').textContent.indexOf('wdiff') != -1);
354         assertTrue(document.querySelector('tbody td:nth-child(2)').textContent.indexOf('pretty diff') == -1);
355     });
356     
357     results = mockResults();
358     var subtree = results.tests['foo'] = {}
359     subtree['bar.html'] = mockExpectation('TEXT', 'PASS');
360     subtree['bar-1.html'] = mockExpectation('TEXT', 'CRASH');
361     subtree['bar-5.html'] = mockExpectation('TEXT', 'IMAGE+TEXT');
362     subtree['bar-3.html'] = mockExpectation('PASS', 'TEXT');
363     subtree['bar-2.html'] = mockExpectation('PASS', 'IMAGE');
364     runTest(results, function() {
365         // FIXME: This just ensures we don't get a JS error.
366         // Verify that the sort is correct and that inline expanded expectations
367         // move along with the test they're attached to.
368         TableSorter.sortColumn(0);
369         TableSorter.sortColumn(0);
370         TableSorter.sortColumn(1);
371         TableSorter.sortColumn(1);
372         TableSorter.sortColumn(2);
373         TableSorter.sortColumn(2);
374         TableSorter.sortColumn(3);
375         TableSorter.sortColumn(3);
376         TableSorter.sortColumn(4);
377         TableSorter.sortColumn(4);
378         TableSorter.sortColumn(0);
379         logPass('PASS');
380     });
381
382     results = mockResults();
383     var subtree = results.tests['foo'] = {}
384     subtree['bar-5.html'] = mockExpectation('TEXT', 'IMAGE+TEXT');
385     runTest(results, function() {
386         expandAllExpectations();
387         var png = document.querySelector('[src*="bar-5-expected.png"]');
388         var x = png.offsetLeft + 1;
389         var y = png.offsetTop + 1;
390         var mockEvent = {
391             target: png,
392             clientX: x,
393             clientY: y
394         }
395         PixelZoomer.showOnDelay = false;
396         PixelZoomer.handleMouseMove(mockEvent);
397         assertTrue(!!document.querySelector('.pixel-zoom-container'));
398         assertTrue(document.querySelectorAll('.zoom-image-container').length == 3);
399     });
400     
401     results = mockResults();
402     var subtree = results.tests['fullscreen'] = {}
403     subtree['full-screen-api.html'] = mockExpectation('TEXT', 'IMAGE+TEXT');
404     runTest(results, function() {
405         // Use a regexp to match windows and unix-style paths.
406         var expectedRegExp = new RegExp('^file.*' + results.layout_tests_dir + '/fullscreen/full-screen-api.html$');
407         assertTrue(expectedRegExp.exec(document.querySelector('tbody td:first-child a').href));
408     });
409
410     var oldShouldUseTracLinks = shouldUseTracLinks;
411     shouldUseTracLinks = function() { return true; };
412     
413     results = mockResults();
414     var subtree = results.tests['fullscreen'] = {}
415     subtree['full-screen-api.html'] = mockExpectation('TEXT', 'IMAGE+TEXT');
416     runTest(results, function() {
417         var expectedHref = 'http://trac.webkit.org/export/' + results.revision + '/trunk/LayoutTests/fullscreen/full-screen-api.html';
418         assertTrue(document.querySelector('tbody td:first-child a').href == expectedHref);
419     });
420
421     results = mockResults();
422     var subtree = results.tests['fullscreen'] = {}
423     subtree['full-screen-api.html'] = mockExpectation('TEXT', 'IMAGE+TEXT');
424     results.revision = '';
425     runTest(results, function() {
426         var expectedHref = 'http://trac.webkit.org/browser/trunk/LayoutTests/fullscreen/full-screen-api.html';
427         assertTrue(document.querySelector('tbody td:first-child a').href == expectedHref);
428     });
429
430     shouldUseTracLinks = oldShouldUseTracLinks;
431
432     results = mockResults();
433     results.tests['bar.html'] = mockExpectation('PASS', 'IMAGE', 1);
434     runTest(results, function() {
435         assertTrue(document.querySelector('tbody td:nth-child(3)').textContent == 'images diff (1%) ');
436
437         document.getElementById('toggle-images').checked = false;
438         // FIXME: We shouldn't need to call updateTogglingImages. Setting checked above should call it.
439         updateTogglingImages();
440         // FIXME: We get extra spaces in the DOM every time we enable/disable image toggling.
441         assertTrue(document.querySelector('tbody td:nth-child(3)').textContent == 'expected actual  diff (1%) ');
442         
443         document.getElementById('toggle-images').checked = true;
444         updateTogglingImages();
445         assertTrue(document.querySelector('tbody td:nth-child(3)').textContent == ' images   diff (1%) ');
446     });
447     
448     results = mockResults();
449     results.tests['reading-options-from-localstorage.html'] = mockExpectation('IMAGE+TEXT', 'IMAGE+TEXT', 1);
450     runTest(results, function() {
451         assertTrue(window.getComputedStyle(document.querySelector('tbody'), null)['display'] != 'none');
452         assertTrue(document.querySelector('tbody td:nth-child(3)').textContent == 'expected actual  diff (1%) ');
453     }, '{"toggle-images":false,"unexpected-results":false}');
454
455     function enclosingNodeWithTagNameHasClassName(node, tagName, className) {
456         while (node && (!node.tagName || node.localName != tagName))
457             node = node.parentNode;
458         if (!node)
459             return false;
460         return node.className == className;
461     }
462
463     results = mockResults();
464     var subtree = results.tests['foo'] = {}
465     subtree['expected-to-pass-but-crashed.html'] = mockExpectation('PASS', 'CRASH');
466     subtree['expected-to-pass-or-crash-and-crashed.html'] = mockExpectation('PASS CRASH', 'CRASH');
467     subtree['expected-to-pass-but-timeouted.html'] = mockExpectation('PASS', 'CRASH');
468     subtree['expected-to-pass-or-timeout-and-timeouted.html'] = mockExpectation('PASS TIMEOUT', 'TIMEOUT');
469     subtree['expected-fail-but-passed.html'] = mockExpectation('FAIL', 'PASS');
470     subtree['expected-pass-or-fail-and-passed.html'] = mockExpectation('PASS FAIL', 'PASS');
471     runTest(results, function() {
472         assertTrue(!document.getElementById('results-table'));
473
474         var testLinks = document.querySelectorAll('.test-link');
475         assertTrue(testLinks[0].innerText == 'foo/expected-to-pass-but-crashed.html');
476         assertTrue(!enclosingNodeWithTagNameHasClassName(testLinks[0], 'tbody', 'expected'));
477         assertTrue(testLinks[1].innerText == 'foo/expected-to-pass-or-crash-and-crashed.html');
478         assertTrue(enclosingNodeWithTagNameHasClassName(testLinks[1], 'tbody', 'expected'));
479         assertTrue(!enclosingNodeWithTagNameHasClassName(testLinks[0], 'table', 'expected'));
480
481         assertTrue(testLinks[2].innerText == 'foo/expected-to-pass-but-timeouted.html');
482         assertTrue(!enclosingNodeWithTagNameHasClassName(testLinks[2], 'tbody', 'expected'));
483         assertTrue(testLinks[3].innerText == 'foo/expected-to-pass-or-timeout-and-timeouted.html');
484         assertTrue(enclosingNodeWithTagNameHasClassName(testLinks[3], 'tbody', 'expected'));
485         assertTrue(!enclosingNodeWithTagNameHasClassName(testLinks[2], 'table', 'expected'));
486
487         assertTrue(testLinks[4].innerText == 'foo/expected-fail-but-passed.html');
488         assertTrue(!enclosingNodeWithTagNameHasClassName(testLinks[4], 'tbody', 'expected'));
489         assertTrue(testLinks[5].innerText == 'foo/expected-pass-or-fail-and-passed.html');
490         assertTrue(enclosingNodeWithTagNameHasClassName(testLinks[5], 'tbody', 'expected'));
491         assertTrue(!enclosingNodeWithTagNameHasClassName(testLinks[4], 'table', 'expected'));
492     });
493
494     results = mockResults();
495     var subtree = results.tests['foo'] = {}
496     subtree['expected-to-pass-or-crash-and-crashed.html'] = mockExpectation('PASS CRASH', 'CRASH');
497     subtree['expected-to-pass-or-timeout-and-timeouted.html'] = mockExpectation('PASS TIMEOUT', 'TIMEOUT');
498     subtree['expected-pass-or-fail-and-passed.html'] = mockExpectation('PASS FAIL', 'PASS');
499     runTest(results, function() {
500         assertTrue(!document.getElementById('results-table'));
501
502         var testLinks = document.querySelectorAll('.test-link');
503         assertTrue(testLinks[0].innerText == 'foo/expected-to-pass-or-crash-and-crashed.html');
504         assertTrue(enclosingNodeWithTagNameHasClassName(testLinks[0], 'tbody', 'expected'));
505         assertTrue(enclosingNodeWithTagNameHasClassName(testLinks[0], 'table', 'expected'));
506
507         assertTrue(testLinks[1].innerText == 'foo/expected-to-pass-or-timeout-and-timeouted.html');
508         assertTrue(enclosingNodeWithTagNameHasClassName(testLinks[1], 'tbody', 'expected'));
509         assertTrue(enclosingNodeWithTagNameHasClassName(testLinks[1], 'table', 'expected'));
510
511         assertTrue(testLinks[2].innerText == 'foo/expected-pass-or-fail-and-passed.html');
512         assertTrue(enclosingNodeWithTagNameHasClassName(testLinks[2], 'tbody', 'expected'));
513         assertTrue(enclosingNodeWithTagNameHasClassName(testLinks[2], 'table', 'expected'));
514     });
515
516     results = mockResults();
517     var subtree = results.tests['foo'] = {}
518     subtree['bar.html'] = mockExpectation('TEXT', 'PASS');
519     subtree['crash.html'] = mockExpectation('IMAGE', 'CRASH');
520     subtree['flaky-fail.html'] = mockExpectation('PASS TEXT', 'IMAGE PASS');
521     runTest(results, function() {
522         assertTrue(!document.getElementById('results-table'));
523
524         var resultText = document.body.textContent;
525         assertTrue(resultText.indexOf('crash.html') != -1);
526         assertTrue(resultText.indexOf('flaky-fail.html') != -1);
527         assertTrue(resultText.indexOf('crash.html') < resultText.indexOf('flaky-fail.html'));
528     });
529
530     results = mockResults();
531     var subtree = results.tests['foo'] = {}
532     subtree['expected-missing.html'] = mockExpectation('MISSING', 'MISSING');
533     subtree['expected-missing.html'].is_missing_text = true;
534     subtree['expected-missing.html'].is_missing_image = true;
535     subtree['unexpected-missing.html'] = mockExpectation('PASS', 'MISSING');
536     subtree['unexpected-missing.html'].is_missing_text = true;
537     runTest(results, function() {
538         assertTrue(!document.getElementById('results-table'));
539         assertTrue(visibleExpandLinks().length == 1);
540         assertTrue(document.querySelector('#missing-table tbody.expected .test-link').textContent == 'foo/expected-missing.html');
541         assertTrue(document.querySelector('#missing-table tbody.expected').getElementsByClassName('result-link')[0].textContent == 'result');
542         assertTrue(document.querySelector('#missing-table tbody.expected').getElementsByClassName('result-link')[1].textContent == 'png result');
543         assertTrue(document.querySelector('#missing-table tbody:not(.expected) .test-link').textContent == 'foo/unexpected-missing.html');
544         assertTrue(document.querySelector('#missing-table tbody:not(.expected) .result-link').textContent == 'result');
545
546         document.getElementById('unexpected-results').checked = false;
547         document.getElementById('unexpected-results').onchange();
548         expandAllExpectations();
549         assertTrue(visibleExpandLinks().length == 2);
550     });
551
552     document.body.innerHTML = '<pre>' + g_log.join('\n') + '</pre>';
553 }
554
555 var originalGeneratePage = generatePage;
556 generatePage = runTests;