| Index: pkg/polymer/lib/elements/web-animations-js/test/test-runner.html
|
| diff --git a/pkg/polymer/lib/elements/web-animations-js/test/test-runner.html b/pkg/polymer/lib/elements/web-animations-js/test/test-runner.html
|
| new file mode 100755
|
| index 0000000000000000000000000000000000000000..e3fc354791b56d3acab3942bc395a430a1264c24
|
| --- /dev/null
|
| +++ b/pkg/polymer/lib/elements/web-animations-js/test/test-runner.html
|
| @@ -0,0 +1,777 @@
|
| +<!--
|
| +Copyright 2012 Google Inc. All Rights Reserved.
|
| +
|
| +Licensed under the Apache License, Version 2.0 (the "License");
|
| +you may not use this file except in compliance with the License.
|
| +You may obtain a copy of the License at
|
| +
|
| + http://www.apache.org/licenses/LICENSE-2.0
|
| +
|
| +Unless required by applicable law or agreed to in writing, software
|
| +distributed under the License is distributed on an "AS IS" BASIS,
|
| +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| +See the License for the specific language governing permissions and
|
| +limitations under the License.
|
| +-->
|
| +<!DOCTYPE html>
|
| +<meta charset="UTF-8">
|
| +
|
| +<style>
|
| +
|
| +#status-box {
|
| + position: fixed;
|
| + bottom: 0;
|
| + right: 0;
|
| + background: white;
|
| + border: 1px solid black;
|
| + padding-right: 5px;
|
| +}
|
| +
|
| +h1 {
|
| + display: inline;
|
| +}
|
| +
|
| +table {
|
| + border-collapse: collapse;
|
| +}
|
| +
|
| +td {
|
| + border: 1px solid black;
|
| +}
|
| +
|
| +iframe {
|
| + width: 800px;
|
| + height: 600px;
|
| +}
|
| +
|
| +tbody {
|
| + color: gray;
|
| +}
|
| +
|
| +td.log ul li {
|
| + white-space: pre;
|
| + font-family: monospace;
|
| +}
|
| +
|
| +/* Fail styles */
|
| +tbody.fail {
|
| + color: red;
|
| +}
|
| +
|
| +li.fail {
|
| + color: red;
|
| +}
|
| +
|
| +tbody.timeout {
|
| + color: yellow;
|
| +}
|
| +
|
| +li.timeout {
|
| + color: yellow;
|
| +}
|
| +
|
| +
|
| +/* Pass styles */
|
| +tbody.pass {
|
| + color: green;
|
| +}
|
| +
|
| +li.pass {
|
| + color: green;
|
| +}
|
| +
|
| +tbody.pass-expected-failure {
|
| + color: #00aa00;
|
| +}
|
| +
|
| +li.pass-expected-failure {
|
| + color: #00aa00;
|
| +}
|
| +
|
| +tbody.skipped {
|
| + color: #00aa00;
|
| +}
|
| +
|
| +li.skipped {
|
| + color: #00aa00;
|
| +}
|
| +
|
| +/* No-test styles */
|
| +tbody.no-tests {
|
| + color: #ff8a00;
|
| +}
|
| +
|
| +</style>
|
| +<script src="browserdetect/bowser.js"></script>
|
| +<script src="testcases.js"></script>
|
| +
|
| +<div id=status-box>
|
| +<h1 id=status>Pending</h1>
|
| +Tests: <span id=tests></span>
|
| +Loading: <span id=loading></span> (<span id=loaded></span>)
|
| +Running: <span id=running></span> (<span id=finished></span>)
|
| +Posting: <span id=posting></span> (<span id=posted></span>)
|
| +</div>
|
| +
|
| +<table id="results"></table>
|
| +<div id="spacer"></div>
|
| +
|
| +<script>
|
| +'use strict';
|
| +window.onerror = function(msg, url, line) {
|
| + // Ignore errors caused by webdriver
|
| + if (msg.match(/webdriver/))
|
| + return;
|
| +
|
| + if (document.getElementById('javascript-errors') == null) {
|
| + document.body.innerHTML = '<pre id="javascript-errors">JAVASCRIPT ERRORS\n\n</pre>';
|
| + }
|
| +
|
| + var e = document.getElementById('javascript-errors');
|
| + var msg = 'Javascript Error in ' + url + '\n' +
|
| + 'Line ' + line + ': ' + msg + '\n';
|
| + e.innerHTML += msg;
|
| +};
|
| +</script>
|
| +
|
| +<script>
|
| +'use strict';
|
| +
|
| +(function() {
|
| +window.finished = false;
|
| +window.getTestRunnerProgress = function() {
|
| + return {
|
| + completed: testStates['POSTED'].length,
|
| + total: tests.length,
|
| + };
|
| +}
|
| +
|
| +var results = [];
|
| +
|
| +if (/coverage/.test(window.location.hash)) {
|
| + // Trigger coverage runs for child tests.
|
| + window.__coverage__ = {};
|
| + // Share resources loaded by child tests to avoid instrumenting the same
|
| + // source file multiple times.
|
| + window.__resources__ = {original: {}};
|
| +}
|
| +
|
| +window.addEventListener('load', function() {
|
| + document.querySelector('#spacer').style.height =
|
| + getComputedStyle(document.querySelector('body')).height;
|
| +});
|
| +function trueOffsetTop(element) {
|
| + var t = 0;
|
| + if (element.offsetParent) {
|
| + do {
|
| + t += element.offsetTop;
|
| + } while (element = element.offsetParent);
|
| + return t;
|
| + }
|
| +}
|
| +
|
| +/**
|
| + * Get a value for busting the cache.
|
| + */
|
| +var cacheBuster = '' + window.Date.now();
|
| +
|
| +/**
|
| + * Get the most accurate version of time possible.
|
| + *
|
| + * @return {number} Time as this very moment.
|
| + */
|
| +function now() {
|
| + try {
|
| + return window.performance.now();
|
| + } catch (e) {
|
| + return Date.now();
|
| + }
|
| +}
|
| +
|
| +/**
|
| + * Creates HTML elements in a table for a test.
|
| + *
|
| + * +-----------+------+-------+
|
| + * | Test Name | Link | Count |
|
| + * +-----------+------+-------+
|
| + * | Log of test run. |
|
| + * +--------------------------+
|
| + * | iFrame containing test |
|
| + * +--------------------------+
|
| + *
|
| + * @param {String} testName Name of the test suite being run.
|
| + * @param {String} testURL The url of the test suite.
|
| + * @return {Element} tbody containing newly created table rows.
|
| + */
|
| +function createTestRows(testName, testURL) {
|
| + var tableGroup = document.createElement('tbody');
|
| + tableGroup.id = testName.replace('.', '-');
|
| +
|
| + var basicInfoRow = document.createElement('tr');
|
| + basicInfoRow.className = 'info-row';
|
| + tableGroup.appendChild(basicInfoRow);
|
| + var iframeRow = document.createElement('tr');
|
| + tableGroup.appendChild(iframeRow);
|
| + var logRow = document.createElement('tr');
|
| + tableGroup.appendChild(logRow);
|
| +
|
| + // Name
|
| + var header = document.createElement('h1');
|
| + header.textContent = testName;
|
| +
|
| + var headerCell = document.createElement('td');
|
| + headerCell.appendChild(header);
|
| + basicInfoRow.appendChild(headerCell);
|
| +
|
| + // Link
|
| + var link = document.createElement('a');
|
| + link.textContent = testName;
|
| + link.href = testURL;
|
| +
|
| + var linkCell = document.createElement('td');
|
| + linkCell.appendChild(link);
|
| + basicInfoRow.appendChild(linkCell);
|
| +
|
| + // Test count
|
| + var countCell = document.createElement('td');
|
| + countCell.className = 'count';
|
| + basicInfoRow.appendChild(countCell);
|
| +
|
| + // Timing info
|
| + var timingCell = document.createElement('td');
|
| + timingCell.className = 'timing';
|
| + basicInfoRow.appendChild(timingCell);
|
| +
|
| + // iframe containing a preview of object
|
| + var iframe = document.createElement('iframe');
|
| + iframe.src = testURL + '?' + cacheBuster + '#message';
|
| +
|
| + var iframeCell = document.createElement('td');
|
| + iframeCell.colSpan = '4';
|
| + iframeCell.appendChild(iframe);
|
| + iframeRow.appendChild(iframeCell);
|
| +
|
| + // table row containing the complete test log
|
| + var logCell = document.createElement('td');
|
| + logCell.className = 'log';
|
| + logCell.colSpan = '4';
|
| + logRow.appendChild(logCell);
|
| +
|
| + /**
|
| + * Normally we would use "display: none;" but that causes Firefox to return
|
| + * null for getComputedStyle, so instead we have to use this visibility hack.
|
| + */
|
| + tableGroup.showInfo = function() {
|
| + logRow.style.visibility = 'visible';
|
| + logRow.style.position = '';
|
| + logRow.style.height = 'auto';
|
| +
|
| + iframeRow.style.visibility = 'visible';
|
| + iframeRow.style.position = '';
|
| + iframeRow.style.height = 'auto';
|
| + };
|
| + tableGroup.hideInfo = function() {
|
| + logRow.style.visibility = 'hidden';
|
| + logRow.style.position = 'absolute';
|
| + logRow.style.height = '0';
|
| +
|
| + iframeRow.style.visibility = 'hidden';
|
| + iframeRow.style.position = 'absolute';
|
| + iframeRow.style.height = '0';
|
| + };
|
| + tableGroup.toggleInfo = function() {
|
| + if (logRow.style.visibility == 'hidden') {
|
| + tableGroup.showInfo();
|
| + } else {
|
| + tableGroup.hideInfo();
|
| + }
|
| + };
|
| + basicInfoRow.onclick = tableGroup.toggleInfo;
|
| +
|
| + tableGroup.hideInfo();
|
| +
|
| + return tableGroup;
|
| +}
|
| +
|
| +/* @type {?number} */ var runTestsId = null;
|
| +
|
| +/**
|
| + * Checks all the tests are in the loaded state and then kicks of running
|
| + * the tests.
|
| + */
|
| +function runTestsIfLoaded() {
|
| + if (testStates['LOADING'].length > 0)
|
| + return;
|
| +
|
| + if (runTestsId == null) {
|
| + runTestsId = window.setInterval(runTests, 10);
|
| + }
|
| +}
|
| +
|
| +function generateCoverageReport() {
|
| + // TODO: generate a pretty report, prompt to save the JSON, post it somewhere
|
| + for (var file in window.__coverage__) {
|
| + var results = window.__coverage__[file];
|
| + var hits = 0;
|
| + var statements = 0;
|
| + for (var stmt in results.s) {
|
| + statements++;
|
| + if (results.s[stmt] > 0) {
|
| + hits++;
|
| + }
|
| + }
|
| + var percent = (100 * hits / statements).toFixed(2);
|
| + console.log(file + ' statement coverage ' +
|
| + percent + '% (' + hits + '/' + statements + ')');
|
| + }
|
| +}
|
| +
|
| +/**
|
| + * This object tracks which state a test is in. An individual test should only
|
| + * ever be in one of the lists. You use the changeTestState() function to move
|
| + * from one state to another.
|
| + *
|
| + * Tests start off in the loading state and move downwards until ending up in
|
| + * the finished state.
|
| + */
|
| +var testStates = {};
|
| +testStates['LOADING'] = []; /* Test which is being loaded. */
|
| +testStates['LOADED'] = []; /* Test which have yet to start. */
|
| +testStates['RUNNING'] = []; /* Test that is currently running. */
|
| +testStates['FINISHED'] = []; /* Test that are finished. */
|
| +testStates['POSTING'] = []; /* Test that is currently posting results to server. */
|
| +testStates['POSTED'] = []; /* Test which have completed and sent their
|
| + results to the server. */
|
| +
|
| +/**
|
| + * Track if we should skip the POSTING state, occurs if posting returns an error.
|
| + */
|
| +/* @type {Boolean} */ var skipPosting = false;
|
| +
|
| +/**
|
| + * Changes the state of the given test to the given state.
|
| + * This function doesn't check that the state transition actually make sense.
|
| + *
|
| + * @param {Element} test DOM object representing the test. The id will contain
|
| + * the test name.
|
| + * @param {States} The new state to transition too.
|
| + */
|
| +function changeTestState(test, newState) {
|
| + var i = null;
|
| +
|
| + if (newState == 'POSTING' && skipPosting) {
|
| + newState = 'POSTED';
|
| + }
|
| +
|
| + var oldState = test.state;
|
| +
|
| + // If we have already posted, we should never leave...
|
| + if (oldState == 'POSTED') {
|
| + throw 'Unexpected state change! Trying to leave POSTED state to ' + newState;
|
| + return;
|
| + }
|
| +
|
| + if (typeof oldState != 'undefined') {
|
| + var i = testStates[oldState].indexOf(test);
|
| + testStates[oldState].splice(i, 1);
|
| + }
|
| +
|
| + test.state = newState;
|
| + testStates[test.state].unshift(test);
|
| +
|
| + function testSort(a, b) {
|
| + return a.id.localeCompare(b.id);
|
| + }
|
| + testStates[test.state].sort(testSort);
|
| +
|
| + switch(newState) {
|
| + case 'LOADING':
|
| + runTestsIfLoaded();
|
| + break;
|
| +
|
| + case 'LOADED':
|
| + if (oldState != 'LOADING') {
|
| + throw 'Unexpected state change! ' + oldState + ' changing to LOADED';
|
| + }
|
| + break;
|
| +
|
| + case 'RUNNING':
|
| + if (oldState != 'LOADED') {
|
| + throw 'Unexpected state change! ' + oldState + ' changing to RUNNING';
|
| + }
|
| +
|
| + test.start = now();
|
| + var testWindow = test.querySelector('iframe').contentWindow;
|
| + var msg = {type: 'start', url: testWindow.location.href + ''};
|
| + testWindow.postMessage(msg, '*');
|
| + break;
|
| +
|
| + case 'FINISHED':
|
| + // If a test doesn't use any timing stuff it could come from the LOADING or
|
| + // LOADED state into the FINISHED state bypassing the RUNNING state.
|
| + if (oldState != 'LOADING' && oldState != 'LOADED' && oldState != 'RUNNING') {
|
| + throw 'Unexpected state change! ' + oldState + ' changing to FINISHED';
|
| + }
|
| +
|
| + var timingInfo = test.querySelector('.timing');
|
| + if (test.start) {
|
| + test.finished = now();
|
| + timingInfo.textContent = (test.finished - test.start).toFixed(2) + 'ms';
|
| + } else {
|
| + timingInfo.textContent = '(Load only)';
|
| + }
|
| +
|
| + var test_iframe = test.querySelector('iframe');
|
| + processResults(test, test_iframe.contentWindow.expected_failures);
|
| +
|
| + break;
|
| +
|
| + case 'POSTING':
|
| + if (oldState != 'FINISHED') {
|
| + throw 'Unexpected state change! ' + oldState + ' changing to POSTING';
|
| + }
|
| +
|
| + if (test.className == 'fail') {
|
| + // Open up the window of the failed result
|
| + test.showInfo();
|
| + // Scroll to it.
|
| + window.scroll(0, trueOffsetTop(test));
|
| + }
|
| +
|
| + // Open the status window for taking of screenshots
|
| + var data = new FormData();
|
| + data.append('data', JSON.stringify(test.results_processed));
|
| +
|
| + var xhr = new XMLHttpRequest();
|
| + xhr.onload = function (e) {
|
| + if (e.target.status >= 400) {
|
| + skipPosting = true;
|
| + }
|
| + // Move from running to finished state
|
| + changeTestState(this, 'POSTED');
|
| + }.bind(test);
|
| + xhr.open('POST', 'test-results-post.html', true);
|
| + xhr.send(data);
|
| +
|
| + break;
|
| +
|
| + case 'POSTED':
|
| + // If we are skipping POSTING, tests can transition straight from FINISHED
|
| + // state into the POSTED state.
|
| + if (oldState != 'POSTING' && (!skipPosting || oldState != 'FINISHED')) {
|
| + throw 'Unexpected state change! ' + oldState + ' changing to POSTED';
|
| + }
|
| + break;
|
| + }
|
| +}
|
| +
|
| +/**
|
| + * Elements for reporting the overall status.
|
| + */
|
| +/* @type {Element} */ var statusElement = document.querySelector('#status');
|
| +
|
| +/* @type {Element} */ var testElement = document.querySelector('#tests');
|
| +
|
| +/* @type {Element} */ var loadingElement = document.querySelector('#loading');
|
| +/* @type {Element} */ var loadedElement = document.querySelector('#loaded');
|
| +
|
| +/* @type {Element} */ var runningElement = document.querySelector('#running');
|
| +/* @type {Element} */ var finishedElement = document.querySelector('#finished');
|
| +
|
| +/* @type {Element} */ var postingElement = document.querySelector('#posting');
|
| +/* @type {Element} */ var postedElement = document.querySelector('#posted');
|
| +
|
| +/**
|
| + * Update the status dialog with information about the current status.
|
| + */
|
| +function updateStatus() {
|
| + testElement.textContent = tests.length;
|
| +
|
| + loadingElement.textContent = testStates['LOADING'].length;
|
| + loadedElement.textContent = testStates['LOADED'].length;
|
| +
|
| + runningElement.textContent = testStates['RUNNING'].length;
|
| + finishedElement.textContent = testStates['FINISHED'].length;
|
| +
|
| + postingElement.textContent = testStates['POSTING'].length;
|
| + postedElement.textContent = testStates['POSTED'].length;
|
| +
|
| + if (testStates['LOADED'].length > 0) {
|
| + statusElement.textContent = 'Loading';
|
| + } else if (testStates['RUNNING'].length > 0) {
|
| + statusElement.textContent = 'Running';
|
| + } else if (testStates['POSTING'].length > 0) {
|
| + statusElement.textContent = 'Posting results';
|
| + } else if (testStates['POSTED'].length == tests.length) {
|
| + statusElement.textContent = 'Finished';
|
| +
|
| + window.clearInterval(updateStatusId);
|
| + window.clearInterval(runTestsId);
|
| + window.finished = true;
|
| + if (window.__coverage__) {
|
| + generateCoverageReport();
|
| + }
|
| + }
|
| +}
|
| +
|
| +/* @type {?number} */ var updateStatusId = setInterval(updateStatus, 100);
|
| +
|
| +
|
| +var testRunners = [];
|
| +
|
| +/**
|
| + * Create the iframes for each test.
|
| + */
|
| +window.onload = function createTestRunners() {
|
| + // Filter the tests
|
| + var filter = window.location.href.split('?')[1];
|
| + if (filter) {
|
| + filter = new RegExp(filter);
|
| + tests = tests.filter(function(v) {
|
| + return filter.exec(v);
|
| + });
|
| + }
|
| +
|
| + function testSort(a, b) {
|
| + a = a.replace('.', '-');
|
| + b = b.replace('.', '-');
|
| + return a.localeCompare(b);
|
| + }
|
| + tests.sort(testSort);
|
| +
|
| + for (var i = 0; i < tests.length; i++) {
|
| + var testName = tests[i];
|
| + var testURL = 'testcases/' + testName;
|
| +
|
| + var test = createTestRows(testName, testURL);
|
| + testRunners.unshift(test);
|
| +
|
| + changeTestState(test, 'LOADING');
|
| +
|
| + document.querySelector('#results').appendChild(test);
|
| + test.querySelector('iframe').contentWindow.onload = function() {
|
| + // You can get multiple onload events, only deal with the first one.
|
| + if (this.state == 'LOADING') {
|
| + changeTestState(this, 'LOADED');
|
| + runTestsIfLoaded();
|
| + }
|
| + }.bind(test);
|
| + }
|
| +
|
| +};
|
| +
|
| +/**
|
| + * Start as many loaded tests as possible, wait for results and then post
|
| + * them.
|
| + */
|
| +function runTests() {
|
| + // Start a test running
|
| + if (testStates['LOADED'].length > 0 &&
|
| + testStates['RUNNING'].length < 1) {
|
| + changeTestState(testStates['LOADED'][0], 'RUNNING');
|
| + }
|
| +
|
| + // Start a test posting
|
| + if (testStates['FINISHED'].length > 0 &&
|
| + testStates['POSTING'].length < 1) {
|
| + changeTestState(testStates['FINISHED'][0], 'POSTING');
|
| + }
|
| +
|
| + // Deal with tests which are taking too long...
|
| + for (var i in testStates['RUNNING']) {
|
| + var test = testStates['RUNNING'][i];
|
| + if (now() - test.start > 300e3) {
|
| + // Only way to stop all the javascript and anything else running in the
|
| + // test is to clear the document.
|
| + var test_iframe = test.querySelector('iframe');
|
| + test_iframe.src = "data:text/html;charset=utf-8,<!DOCTYPE html><html><body>TIMEOUT</body></html>";
|
| +
|
| + test.results_raw = [];
|
| + changeTestState(test, 'FINISHED');
|
| + }
|
| + }
|
| +}
|
| +
|
| +/* @type {Object.<string, Object>} */ var testResults = {};
|
| +/**
|
| + * Callback that occurs when the test has finished running.
|
| + */
|
| +window.addEventListener(
|
| + 'message',
|
| + function(evt) {
|
| + // If the test timed out, this will fail with a cross-origin error.
|
| + try {
|
| + var testname = evt.source.location.pathname.split('/').pop().replace('.', '-');
|
| + } catch (e) {
|
| + return;
|
| + }
|
| +
|
| + var test = document.getElementById(testname);
|
| +
|
| + // We only respond to complete as postMessage doesn't guarantee order so
|
| + // result messages can come in after the complete message.
|
| + if (evt.data['type'] != 'complete')
|
| + return;
|
| +
|
| + // Try changing to state FINISHED, but this message may be after the a
|
| + // timeout or transition.
|
| + try {
|
| + test.results_raw = evt.data['tests'];
|
| + changeTestState(test, 'FINISHED');
|
| + } catch (e) {
|
| + console.warn(e);
|
| + }
|
| + },
|
| + false);
|
| +
|
| +
|
| +/**
|
| + * Processes the test's results and put the information into the test object.
|
| + *
|
| + * @param {Element} test DOM object representing the test.
|
| + * @param {Array.<Object>} results List of testharness.js result objects.
|
| + */
|
| +function processResults(test, expected_failures) {
|
| + var browser_expected_failures = {};
|
| + for(var tname in expected_failures) {
|
| + for(var bname in bowser) {
|
| + var fails = expected_failures[tname][bname];
|
| + if ((typeof fails != "undefined") &&
|
| + (typeof fails == "boolean" && fails) ||
|
| + (typeof fails == "object" && fails.indexOf(bowser.version) != -1)) {
|
| + browser_expected_failures[tname] = expected_failures[tname];
|
| + }
|
| + }
|
| + }
|
| +
|
| + var counts = {
|
| + passed: 0,
|
| + failed: 0,
|
| + skipped: 0,
|
| + expected_failed: 0, // This count is included in the above
|
| + total: test.results_raw.length
|
| + };
|
| + var results = [];
|
| + var newResultsDiv = document.createElement('ul');
|
| +
|
| + for(var i = 0; i < test.results_raw.length; i++) {
|
| + var result = test.results_raw[i];
|
| + results[i] = result;
|
| +
|
| + // Invert expected_failures
|
| + var expected_failure = null;
|
| + for(var tname in browser_expected_failures) {
|
| + var tomatch = tname;
|
| + if (tname.charAt(0) == '/' && tname.charAt(tname.length-1) == '/') {
|
| + tomatch = new RegExp(tname.substr(1, tname.length-2));
|
| + }
|
| + if (result['name'].match(tomatch)) {
|
| + expected_failure = browser_expected_failures[tname];
|
| + }
|
| + }
|
| + if (expected_failure !== null && result.status != result.NOTRUN) {
|
| + if (result.status != result.FAIL) {
|
| + result.message = "Expected failure (" + expected_failure.message + "), actually " +
|
| + {0: 'PASS', 2: 'TIMEOUT', 3:'NOTRUN'}[result.status] + " " +
|
| + result.message;
|
| + result.status = result.FAIL;
|
| + } else {
|
| + result.status = result.PASS;
|
| + result.message = "Expected failure (" + expected_failure.message + "): " + result.message;
|
| + }
|
| + counts.expected_failed++;
|
| + }
|
| +
|
| + var output = document.createElement('li');
|
| + output.innerHTML += result.name + ': ';
|
| +
|
| + switch (result.status) {
|
| + case result.PASS:
|
| + if (!expected_failure) {
|
| + output.className = 'pass';
|
| + } else {
|
| + output.className = 'pass-expected-failure';
|
| + }
|
| + counts.passed++;
|
| + break;
|
| +
|
| + case result.TIMEOUT:
|
| + output.className = 'timeout';
|
| + counts.failed++;
|
| + break;
|
| +
|
| + case result.NOTRUN:
|
| + output.className = 'skipped';
|
| + counts.skipped++;
|
| + break;
|
| +
|
| + case result.FAIL:
|
| + default:
|
| + output.className = 'failed';
|
| + counts.failed++;
|
| + }
|
| +
|
| + output.innerHTML += output.className;
|
| + if (result.message != null) {
|
| + output.innerHTML += ' - ' + result.message;
|
| + }
|
| + newResultsDiv.appendChild(output);
|
| + }
|
| + test.querySelector('.log').appendChild(newResultsDiv);
|
| +
|
| + var debug = '';
|
| + try {
|
| + debug = test.querySelector('iframe').contentDocument.getElementById('debug').innerText;
|
| + } catch (e) {
|
| + debug = 'No debug... :(';
|
| + }
|
| +
|
| + if (counts.total > 0) {
|
| + test.results_processed = {
|
| + type: 'result',
|
| + testName: test.id,
|
| + results: results,
|
| + debug: debug
|
| + };
|
| +
|
| + if (counts.failed == 0) {
|
| + if (counts.expected_failed > 0) {
|
| + test.className = 'pass-expected-failure';
|
| + } else if (counts.skipped > 0) {
|
| + test.className = 'skipped';
|
| + } else {
|
| + test.className = 'pass';
|
| + }
|
| + } else {
|
| + test.className = 'fail';
|
| + }
|
| +
|
| + var summary = counts.total + ' tests; ';
|
| + if (counts.passed > 0) {
|
| + summary += ' ' + counts.passed + ' passed';
|
| + if (counts.expected_failed > 0) {
|
| + summary += ' (with ' + counts.expected_failed + ' expected failures)';
|
| + }
|
| + }
|
| + if (counts.failed > 0) {
|
| + summary += ' ' + counts.failed + ' failed';
|
| + }
|
| + if (counts.skipped > 0) {
|
| + summary += ' ' + counts.skipped + ' skipped';
|
| + }
|
| + test.querySelector('.count').textContent = summary;
|
| + } else {
|
| + test.results_processed = {
|
| + type: 'result',
|
| + testName: test.id,
|
| + results: [],
|
| + };
|
| + test.className = 'no-tests';
|
| + test.querySelector('.count').textContent = 'TIMEOUT';
|
| + }
|
| +}
|
| +
|
| +})();
|
| +
|
| +
|
| +</script>
|
|
|