15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (c) 2010 Google Inc. All rights reserved. 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions are 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * met: 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Redistributions of source code must retain the above copyright 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer. 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Redistributions in binary form must reproduce the above 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * copyright notice, this list of conditions and the following disclaimer 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * in the documentation and/or other materials provided with the 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * distribution. 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Neither the name of Google Inc. nor the names of its 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * contributors may be used to endorse or promote products derived from 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * this software without specific prior written permission. 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)var ALL_DIRECTORY_PATH = '[all]'; 325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)var STATE_NEEDS_REBASELINE = 'needs_rebaseline'; 345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)var STATE_REBASELINE_FAILED = 'rebaseline_failed'; 355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)var STATE_REBASELINE_SUCCEEDED = 'rebaseline_succeeded'; 365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)var STATE_IN_QUEUE = 'in_queue'; 375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)var STATE_TO_DISPLAY_STATE = {}; 385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)STATE_TO_DISPLAY_STATE[STATE_NEEDS_REBASELINE] = 'Needs rebaseline'; 395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)STATE_TO_DISPLAY_STATE[STATE_REBASELINE_FAILED] = 'Rebaseline failed'; 405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)STATE_TO_DISPLAY_STATE[STATE_REBASELINE_SUCCEEDED] = 'Rebaseline succeeded'; 415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)STATE_TO_DISPLAY_STATE[STATE_IN_QUEUE] = 'In queue'; 425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)var results; 445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)var testsByFailureType = {}; 455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)var testsByDirectory = {}; 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)var selectedTests = []; 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)var loupe; 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)var queue; 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)var shouldSortTestsByMetric = false; 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)function main() 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) $('failure-type-selector').addEventListener('change', selectFailureType); 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) $('directory-selector').addEventListener('change', selectDirectory); 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) $('test-selector').addEventListener('change', selectTest); 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) $('next-test').addEventListener('click', nextTest); 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) $('previous-test').addEventListener('click', previousTest); 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) $('toggle-log').addEventListener('click', function() { toggle('log'); }); 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) disableSorting(); 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) loupe = new Loupe(); 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) queue = new RebaselineQueue(); 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) document.addEventListener('keydown', function(event) { 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) { 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (event.keyIdentifier) { 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case 'Left': 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) event.preventDefault(); 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) previousTest(); 745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case 'Right': 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) event.preventDefault(); 775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) nextTest(); 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case 'U+0051': // q 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) queue.addCurrentTest(); 815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case 'U+0058': // x 835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) queue.removeCurrentTest(); 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case 'U+0052': // r 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) queue.rebaseline(); 875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }); 905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) loadText('/platforms.json', function(text) { 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var platforms = JSON.parse(text); 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) platforms.platforms.forEach(function(platform) { 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var platformOption = document.createElement('option'); 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) platformOption.value = platform; 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) platformOption.textContent = platform; 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var targetOption = platformOption.cloneNode(true); 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) targetOption.selected = platform == platforms.defaultPlatform; 1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) $('baseline-target').appendChild(targetOption); 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) $('baseline-move-to').appendChild(platformOption.cloneNode(true)); 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }); 1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }); 1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) loadText('/results.json', function(text) { 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) results = JSON.parse(text); 1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) displayResults(); 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }); 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/** 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Groups test results by failure type. 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)function displayResults() 1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var failureTypeSelector = $('failure-type-selector'); 1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var failureTypes = []; 1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (var testName in results.tests) { 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var test = results.tests[testName]; 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (test.actual == 'PASS') { 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continue; 1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var failureType = test.actual + ' (expected ' + test.expected + ')'; 1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!(failureType in testsByFailureType)) { 1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) testsByFailureType[failureType] = []; 1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) failureTypes.push(failureType); 1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) testsByFailureType[failureType].push(testName); 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Sort by number of failures 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) failureTypes.sort(function(a, b) { 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return testsByFailureType[b].length - testsByFailureType[a].length; 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }); 1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (var i = 0, failureType; failureType = failureTypes[i]; i++) { 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var failureTypeOption = document.createElement('option'); 1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) failureTypeOption.value = failureType; 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) failureTypeOption.textContent = failureType + ' - ' + testsByFailureType[failureType].length + ' tests'; 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) failureTypeSelector.appendChild(failureTypeOption); 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) selectFailureType(); 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) document.body.className = ''; 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)function enableSorting() 1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) $('toggle-sort').onclick = function() { 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) shouldSortTestsByMetric = !shouldSortTestsByMetric; 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Regenerates the list of tests; this alphabetizes, and 1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // then re-sorts if we turned sorting on. 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) selectDirectory(); 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) $('toggle-sort').classList.remove('disabled-control'); 1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)function disableSorting() 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) $('toggle-sort').onclick = function() { return false; } 1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) $('toggle-sort').classList.add('disabled-control'); 1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/** 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * For a given failure type, gets all the tests and groups them by directory 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (populating the directory selector with them). 1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)function selectFailureType() 1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var selectedFailureType = getSelectValue('failure-type-selector'); 1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var tests = testsByFailureType[selectedFailureType]; 1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) testsByDirectory = {} 1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var displayDirectoryNamesByDirectory = {}; 1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var directories = []; 1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Include a special option for all tests 1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) testsByDirectory[ALL_DIRECTORY_PATH] = tests; 1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) displayDirectoryNamesByDirectory[ALL_DIRECTORY_PATH] = 'all'; 1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) directories.push(ALL_DIRECTORY_PATH); 1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Roll up tests by ancestor directories 1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) tests.forEach(function(test) { 1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var pathPieces = test.split('/'); 1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var pathDirectories = pathPieces.slice(0, pathPieces.length -1); 1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var ancestorDirectory = ''; 1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) pathDirectories.forEach(function(pathDirectory, index) { 1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ancestorDirectory += pathDirectory + '/'; 1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!(ancestorDirectory in testsByDirectory)) { 1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) testsByDirectory[ancestorDirectory] = []; 1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var displayDirectoryName = new Array(index * 6).join(' ') + pathDirectory; 1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) displayDirectoryNamesByDirectory[ancestorDirectory] = displayDirectoryName; 1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) directories.push(ancestorDirectory); 1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) testsByDirectory[ancestorDirectory].push(test); 2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }); 2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }); 2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) directories.sort(); 2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var directorySelector = $('directory-selector'); 2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) directorySelector.innerHTML = ''; 2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) directories.forEach(function(directory) { 2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var directoryOption = document.createElement('option'); 2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) directoryOption.value = directory; 2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) directoryOption.innerHTML = 2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) displayDirectoryNamesByDirectory[directory] + ' - ' + 2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) testsByDirectory[directory].length + ' tests'; 2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) directorySelector.appendChild(directoryOption); 2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }); 2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) selectDirectory(); 2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/** 2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * For a given failure type and directory and failure type, gets all the tests 2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * in that directory and populatest the test selector with them. 2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)function selectDirectory() 2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var previouslySelectedTest = getSelectedTest(); 2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var selectedDirectory = getSelectValue('directory-selector'); 2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) selectedTests = testsByDirectory[selectedDirectory]; 2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) selectedTests.sort(); 2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var testsByState = {}; 2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) selectedTests.forEach(function(testName) { 2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var state = results.tests[testName].state; 2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (state == STATE_IN_QUEUE) { 2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) state = STATE_NEEDS_REBASELINE; 2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!(state in testsByState)) { 2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) testsByState[state] = []; 2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) testsByState[state].push(testName); 2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }); 2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var optionIndexByTest = {}; 2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var testSelector = $('test-selector'); 2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) testSelector.innerHTML = ''; 2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var selectedFailureType = getSelectValue('failure-type-selector'); 2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var sampleSelectedTest = testsByFailureType[selectedFailureType][0]; 2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var selectedTypeIsSortable = 'metric' in results.tests[sampleSelectedTest]; 2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (selectedTypeIsSortable) { 2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) enableSorting(); 2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (shouldSortTestsByMetric) { 2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (var state in testsByState) { 2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) testsByState[state].sort(function(a, b) { 2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return results.tests[b].metric - results.tests[a].metric 2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }) 2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else 2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) disableSorting(); 2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (var state in testsByState) { 2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var stateOption = document.createElement('option'); 2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) stateOption.textContent = STATE_TO_DISPLAY_STATE[state]; 2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) stateOption.disabled = true; 2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) testSelector.appendChild(stateOption); 2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) testsByState[state].forEach(function(testName) { 2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var testOption = document.createElement('option'); 2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) testOption.value = testName; 2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var testDisplayName = testName; 2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (testName.lastIndexOf(selectedDirectory) == 0) { 2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) testDisplayName = testName.substring(selectedDirectory.length); 2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) testOption.innerHTML = ' ' + testDisplayName; 2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) optionIndexByTest[testName] = testSelector.options.length; 2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) testSelector.appendChild(testOption); 2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }); 2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (previouslySelectedTest in optionIndexByTest) { 2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) testSelector.selectedIndex = optionIndexByTest[previouslySelectedTest]; 2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else if (STATE_NEEDS_REBASELINE in testsByState) { 2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) testSelector.selectedIndex = 2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) optionIndexByTest[testsByState[STATE_NEEDS_REBASELINE][0]]; 2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) selectTest(); 2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) testSelector.selectedIndex = 1; 2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) selectTest(); 2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) selectTest(); 2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)function getSelectedTest() 2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return getSelectValue('test-selector'); 3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)function selectTest() 3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var selectedTest = getSelectedTest(); 3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (results.tests[selectedTest].actual.indexOf('IMAGE') != -1) { 3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) $('image-outputs').style.display = ''; 3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) displayImageResults(selectedTest); 3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) $('image-outputs').style.display = 'none'; 3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (results.tests[selectedTest].actual.indexOf('TEXT') != -1) { 3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) $('text-outputs').style.display = ''; 3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) displayTextResults(selectedTest); 3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 3175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) $('text-outputs').style.display = 'none'; 3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var currentBaselines = $('current-baselines'); 3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) currentBaselines.textContent = ''; 3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var baselines = results.tests[selectedTest].baselines; 3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var testName = selectedTest.split('.').slice(0, -1).join('.'); 3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) getSortedKeys(baselines).forEach(function(platform, i) { 3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (i != 0) { 3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) currentBaselines.appendChild(document.createTextNode('; ')); 3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var platformName = document.createElement('span'); 3295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) platformName.className = 'platform'; 3305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) platformName.textContent = platform; 3315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) currentBaselines.appendChild(platformName); 3325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) currentBaselines.appendChild(document.createTextNode(' (')); 3335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) getSortedKeys(baselines[platform]).forEach(function(extension, j) { 3345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (j != 0) { 3355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) currentBaselines.appendChild(document.createTextNode(', ')); 3365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var link = document.createElement('a'); 3385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var baselinePath = ''; 3395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (platform != 'base') { 3405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) baselinePath += 'platform/' + platform + '/'; 3415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) baselinePath += testName + '-expected' + extension; 3435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) link.href = getTracUrl(baselinePath); 3445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (extension == '.checksum') { 3455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) link.textContent = 'chk'; 3465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 3475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) link.textContent = extension.substring(1); 3485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) link.target = '_blank'; 3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (baselines[platform][extension]) { 3515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) link.className = 'was-used-for-test'; 3525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) currentBaselines.appendChild(link); 3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }); 3555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) currentBaselines.appendChild(document.createTextNode(')')); 3565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }); 3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) updateState(); 3595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) loupe.hide(); 3605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) prefetchNextImageTest(); 3625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)function prefetchNextImageTest() 3655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var testSelector = $('test-selector'); 3675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (testSelector.selectedIndex == testSelector.options.length - 1) { 3685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 3695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var nextTest = testSelector.options[testSelector.selectedIndex + 1].value; 3715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (results.tests[nextTest].actual.indexOf('IMAGE') != -1) { 3725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) new Image().src = getTestResultUrl(nextTest, 'expected-image'); 3735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) new Image().src = getTestResultUrl(nextTest, 'actual-image'); 3745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)function updateState() 3785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var testName = getSelectedTest(); 3805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var testIndex = selectedTests.indexOf(testName); 3815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var testCount = selectedTests.length 3825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) $('test-index').textContent = testIndex + 1; 3835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) $('test-count').textContent = testCount; 3845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) $('next-test').disabled = testIndex == testCount - 1; 3865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) $('previous-test').disabled = testIndex == 0; 3875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) $('test-link').href = getTracUrl(testName); 3895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var state = results.tests[testName].state; 3915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) $('state').className = state; 3925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) $('state').innerHTML = STATE_TO_DISPLAY_STATE[state]; 3935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) queue.updateState(); 3955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)function getTestResultUrl(testName, mode) 3985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return '/test_result?test=' + testName + '&mode=' + mode; 4005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)var currentExpectedImageTest; 4035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)var currentActualImageTest; 4045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)function displayImageResults(testName) 4065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (currentExpectedImageTest == currentActualImageTest 4085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) && currentExpectedImageTest == testName) { 4095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 4105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) function displayImageResult(mode, callback) { 4135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var image = $(mode); 4145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) image.className = 'loading'; 4155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) image.src = getTestResultUrl(testName, mode); 4165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) image.onload = function() { 4175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) image.className = ''; 4185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) callback(); 4195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) updateImageDiff(); 4205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }; 4215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) displayImageResult( 4245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 'expected-image', 4255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) function() { currentExpectedImageTest = testName; }); 4265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) displayImageResult( 4275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 'actual-image', 4285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) function() { currentActualImageTest = testName; }); 4295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) $('diff-canvas').className = 'loading'; 4315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) $('diff-canvas').style.display = ''; 4325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) $('diff-checksum').style.display = 'none'; 4335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/** 4365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Computes a graphical a diff between the expected and actual images by 4375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * rendering each to a canvas, getting the image data, and comparing the RGBA 4385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * components of each pixel. The output is put into the diff canvas, with 4395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * identical pixels appearing at 12.5% opacity and different pixels being 4405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * highlighted in red. 4415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 4425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)function updateImageDiff() { 4435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (currentExpectedImageTest != currentActualImageTest) 4445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 4455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var expectedImage = $('expected-image'); 4475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var actualImage = $('actual-image'); 4485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) function getImageData(image) { 4505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var imageCanvas = document.createElement('canvas'); 4515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) imageCanvas.width = image.width; 4525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) imageCanvas.height = image.height; 4535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) imageCanvasContext = imageCanvas.getContext('2d'); 4545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) imageCanvasContext.fillStyle = 'rgba(255, 255, 255, 1)'; 4565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) imageCanvasContext.fillRect( 4575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 0, 0, image.width, image.height); 4585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) imageCanvasContext.drawImage(image, 0, 0); 4605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return imageCanvasContext.getImageData( 4615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 0, 0, image.width, image.height); 4625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var expectedImageData = getImageData(expectedImage); 4655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var actualImageData = getImageData(actualImage); 4665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var diffCanvas = $('diff-canvas'); 4685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var diffCanvasContext = diffCanvas.getContext('2d'); 4695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var diffImageData = 4705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) diffCanvasContext.createImageData(diffCanvas.width, diffCanvas.height); 4715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Avoiding property lookups for all these during the per-pixel loop below 4735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // provides a significant performance benefit. 4745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var expectedWidth = expectedImage.width; 4755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var expectedHeight = expectedImage.height; 4765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var expected = expectedImageData.data; 4775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var actualWidth = actualImage.width; 4795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var actual = actualImageData.data; 4805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var diffWidth = diffImageData.width; 4825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var diff = diffImageData.data; 4835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var hadDiff = false; 4855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (var x = 0; x < expectedWidth; x++) { 4865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (var y = 0; y < expectedHeight; y++) { 4875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var expectedOffset = (y * expectedWidth + x) * 4; 4885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var actualOffset = (y * actualWidth + x) * 4; 4895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var diffOffset = (y * diffWidth + x) * 4; 4905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (expected[expectedOffset] != actual[actualOffset] || 4915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) expected[expectedOffset + 1] != actual[actualOffset + 1] || 4925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) expected[expectedOffset + 2] != actual[actualOffset + 2] || 4935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) expected[expectedOffset + 3] != actual[actualOffset + 3]) { 4945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) hadDiff = true; 4955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) diff[diffOffset] = 255; 4965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) diff[diffOffset + 1] = 0; 4975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) diff[diffOffset + 2] = 0; 4985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) diff[diffOffset + 3] = 255; 4995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 5005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) diff[diffOffset] = expected[expectedOffset]; 5015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) diff[diffOffset + 1] = expected[expectedOffset + 1]; 5025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) diff[diffOffset + 2] = expected[expectedOffset + 2]; 5035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) diff[diffOffset + 3] = 32; 5045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) diffCanvasContext.putImageData( 5095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) diffImageData, 5105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 0, 0, 5115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 0, 0, 5125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) diffImageData.width, diffImageData.height); 5135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) diffCanvas.className = ''; 5145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!hadDiff) { 5165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) diffCanvas.style.display = 'none'; 5175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) $('diff-checksum').style.display = ''; 5185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) loadTextResult(currentExpectedImageTest, 'expected-checksum'); 5195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) loadTextResult(currentExpectedImageTest, 'actual-checksum'); 5205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)function loadTextResult(testName, mode, responseIsHtml) 5245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) loadText(getTestResultUrl(testName, mode), function(text) { 5265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (responseIsHtml) { 5275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) $(mode).innerHTML = text; 5285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 5295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) $(mode).textContent = text; 5305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }); 5325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)function displayTextResults(testName) 5355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) loadTextResult(testName, 'expected-text'); 5375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) loadTextResult(testName, 'actual-text'); 5385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) loadTextResult(testName, 'diff-text-pretty', true); 5395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)function nextTest() 5425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var testSelector = $('test-selector'); 5445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var nextTestIndex = testSelector.selectedIndex + 1; 5455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (true) { 5465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (nextTestIndex == testSelector.options.length) { 5475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 5485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (testSelector.options[nextTestIndex].disabled) { 5505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) nextTestIndex++; 5515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 5525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) testSelector.selectedIndex = nextTestIndex; 5535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) selectTest(); 5545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 5555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)function previousTest() 5605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var testSelector = $('test-selector'); 5625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var previousTestIndex = testSelector.selectedIndex - 1; 5635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (true) { 5645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (previousTestIndex == -1) { 5655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 5665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (testSelector.options[previousTestIndex].disabled) { 5685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) previousTestIndex--; 5695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 5705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) testSelector.selectedIndex = previousTestIndex; 5715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) selectTest(); 5725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 5735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)window.addEventListener('DOMContentLoaded', main); 578