/** * 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. */ /** * @fileoverview Logger class that takes the results array, and outputs each * of the result in HTML format. Uses CSS styles defined in test.css.
* This class renders two tables primarily. The first table that is rendered is * a progress table where tests are listed and as they finish the table is * updated to reflect the status of the tests, the second table rendered are the * actual results of the tests with all its internal assertions and * sub-results.
* Both tables look alike the only difference is that they use different styles * to display, as mentioned above styles are taken from the tests.css file.
* The first table: Progress report
* The first table displays the header and all the id's of the tests along with * an area for the tests to report it's status.
* This table uses little styles but still look a lot alike than its complete * counterpart (see below).
* The tests usually reports a change in its status by using callbacks that will * look for specific div elements using its Id's thus allowing change in the * contents of the DIVs.
* The second table: Results report
* This table looks similar to the first one with notable differences. * One and maybe the most important is that it has all the result information * for each tests, this information is displayed as tables that has more data * than the progress table.
* The second difference is the use of styles to display this table, in fact an * effective way to know if this table is displayed and not it's counterpart is * to look for the 'header' style class since when this style is present in the * rendered div it means that the results have been rendered.
* The information rendered by this logger varies from result to result, * successful tests only displays the id, name and actual result, while * failures and warnings displays the id, name, actual and expected results; if * there is an exception the result is marked as failed and also the exception * is logged in a special format that allows better readability of them. * Information results (log messages) will display their id and the data * logged.
* Also for each test a mini-summary is presented, this contains the outcomes of * the sub-results.
* At the top level there is a summary along with links to the failed tests. */ /** * Creates a new HtmlLogger to render tests results as HTML in a given element. * @param {element} outputDiv The element where the output will be logged. * @param {string} headerMessage A message to be printed in the header of the * test area. * @param {TestSuiteDirectory} testSuiteDirectory to be executed * @constructor */ function HtmlLogger(outputDiv, headerMessage, testSuiteDirectory) { this.outputDiv = outputDiv; this.headerMessage = headerMessage; this.testSuiteDirectory = testSuiteDirectory; this.directoryPassed = true; this.summaryResult = 0; this.statusClassName = ['pass', 'unv', 'warn', 'fail']; this.priorityFailInfo = {}; this.priorityFailInfo[Test.PRIORITY.P4] = []; this.priorityFailInfo[Test.PRIORITY.P3] = []; this.priorityFailInfo[Test.PRIORITY.P2] = []; this.priorityFailInfo[Test.PRIORITY.P1] = []; this.priorityFailInfo[Test.PRIORITY.P0] = []; } /** * Creates table for each test which will be filled when the result is * available. * @param {Test} test to be displayed * @return {string} HTML table for the test */ HtmlLogger.prototype.createTestTableEntry = function(test) { return '' + '
'; }; /** * Returns new HTML results summary table * @param {string} suiteId locator for suite * @return {string} HTML table for test suite summary tabulation */ HtmlLogger.prototype.createSuiteSummaryTable = function(suiteId) { return '' + '' + '' + '' + '' + '' + '' + '
PassedFailedWarningsUnverifiedTotal
00000
'; }; /** * Prepares the report format. This report is shown when tests are launched * and as tests begin to finish it is updated with other details.
* As test completes results are added (hidden initially) and summary table * is updated. */ HtmlLogger.prototype.logTestGrid = function() { var html = []; var hidden = this.testSuiteDirectory.suites.length > 1; // header if (this.headerMessage) { html.push(''); html.push('
' + this.headerMessage); html.push('
' + 'Note: Please ignore any flash or messages that appear. ' + 'They are generated from our tests.' + '
'); } // Gadget Summary html.push(''); html.push(''); html.push('
'); html.push('Executing...'); html.push(this.testSuiteDirectory.name + '' + this.createSuiteSummaryTable('TOTAL') + '
' + 'Generate XML report' + '
'); html.push('' + '
'); html.push(''); var allResults = []; var failCases = 0; var totalCases = 0; for (var i = 0; i < this.testSuiteDirectory.suites.length; i++) { var suiteId = this.testSuiteDirectory.suites[i].id; var tests = this.testSuiteDirectory.suites[i].tests; var suiteName = this.testSuiteDirectory.suites[i].name; // generate results body for suite var htmlBody = []; var manualTests = 0; for (var j = 0; j < tests.length; j++) { if (tests[j].manual) { manualTests += 1; } htmlBody.push(this.createTestTableEntry(tests[j])); } // Suite Summary html.push(''); html.push(''); // print suiteSummaryTable html.push(''); html.push('
'); html.push(''); html.push(''); html.push('' + suiteName + '') html.push(this.createSuiteSummaryTable(suiteId)); html.push('
'); } // footer - json script html.push('' + '
'); html.push(''); html.push(''); html.push(''); html.push('
Results:'); html.push(''); html.push('Baseline Results:'); html.push('
'); this.outputDiv.innerHTML = html.join(''); if (self.gadgets && gadgets.window && gadgets.window.adjustHeight) { // Do this only if dynamic height is supported. This is useful when it's // run inside the orkut container, for example. gadgets.window.adjustHeight(); } }; /** * Displays form to set required fields for restful testing. * @param finishCallback */ HtmlLogger.prototype.restfulPreTestDialog = function(finishCallback) { if (Config.ready || Config.baseUrl != null && Config.securityToken != null) { Config.ready = true; this.logTestGrid(); finishCallback(); return; } HtmlLoggerUtils.logger = this; HtmlLoggerUtils.callback = finishCallback; var html = []; html.push(''); if (Config.baseUrl == null) { html.push('' + '' + ''); } if (Config.securityToken == null) { html.push(''); html.push(''); } html.push('
Sample url: http://BASEURL?field=value1&' + 'TOKEN-PREFIX=SECURITY-TOKEN'); html.push('
'); html.push('Enter details to continue testing.
Base URL:
Security Token Prefix:' + '
Security Token:' + '' + '
' + '
'); this.outputDiv.innerHTML = html.join(''); }; /** * Sets up the config file for restful testing. Displays test grid and calls * callback. */ HtmlLogger.prototype.handleRestfulPreTestConfig = function() { var baseUrl = document.getElementById('baseUrl'); baseUrl = baseUrl ? baseUrl.value : Config.baseUrl; var tokenPrefix = document.getElementById('tokenPrefix'); tokenPrefix = tokenPrefix ? tokenPrefix.value : Config.tokenPrefix; var securityToken = document.getElementById('securityToken'); securityToken = securityToken ? tokenPrefix + '=' + securityToken.value : Config.securityToken; Config.saveUrls(baseUrl, securityToken); this.logTestGrid(); HtmlLoggerUtils.callback(); }; /** * Updates result for the executed test. This method is called to log result * each time test is executed. It performs following tasks
* 1. It creates entry for the test
* 2. Notes if the test result is different from golden result
* 3. It adds bugs link for known bugs for the test
* 4. Adds buttons to re-run and expand/collapse sub-results * * @param {ResultGroup} result of the test executed */ HtmlLogger.prototype.updateTestResult = function(result) { var tableElem = document.getElementById('table_' + result.test.id); var newRowLoc = tableElem.rows.length; tableElem.insertRow(newRowLoc); var newRow = tableElem.rows[newRowLoc]; newRow.style.display = 'table-row'; var changeStatus = (result.delta) ? 'broken' : 'fixed'; var className = 'category'; className += result.delta ? ('-changed-' + changeStatus) : ''; newRow.className = className; var time = result.startTime && result.finishtime ? ' [' + (result.finishtime - result.startTime) + ' ms] ' : ''; var isStableTest = Assert.arrayContains(result.tags, 'stable'); var entry = []; entry.push(''); entry.push(''); entry.push('[' + result.id + '] [' + (result.test.priority ? result.test.priority : Test.PRIORITY.P2) + ' ]:: '); entry.push(' '); entry.push(result.name); entry.push(': '); if (result.severity < Result.severity.PASS) { result.severity = Result.severity.UNVERIFIED; } entry.push('' + Result.severity.getString(result.severity) + ''); if (result.delta) { entry.push('[CHANGED FROM LAST RUN]'); } entry.push(time); // Display if the test is marked as stable. if (result.tags && result.tags.length > 0) { if (isStableTest) { entry.push('
Stable Test'); } } // Display test result roll up. var total = result.getTotal(); if (Config.internal && Config.internal == true) { // Display test case associated bugs links. if (result.bugs && result.bugs.length > 0) { entry.push('
Bugs: '); for (var i = 0; i < result.bugs.length; i++) { entry.push('' + result.bugs[i] + ' '); } } } var hidden = !result.delta && total.warnings == 0 && total.failed == 0; // Add Run Again button. entry.push('
'); entry.push(''); entry.push(''); newRow.innerHTML = entry.join(''); for (var j = result.verifications.length - 1; j >= 0; j--) { this.addVerifications(result.verifications[j], result.test.id, hidden); } if (result.test.description) { this.addDescription(result.test, hidden); } }; /** * Creates one HTML table row for the test description * @param {TestCase} test testcase whose description to be printed * @param {boolean} hidden whether the row to be displayed in the beginning */ HtmlLogger.prototype.addDescription = function(test, hidden) { var tableElem = document.getElementById('table_' + test.id); tableElem.insertRow(1); var newRow = tableElem.rows[1]; if (hidden) { newRow.style.display = 'none'; } newRow.className = 'verification'; newRow.innerHTML = '' + 'Description> ' + test.description + ''; }; /** * Creates one HTML row for the result object (ResultValidation). * @param {ResultValidation} result to convert to HTML * @param {string} testId id of the test case * @param {boolean} hidden whether the row should be hidden or displayed. * If set to true, the row will have display style none */ HtmlLogger.prototype.addVerifications = function(result, testId, hidden) { var tableElem = document.getElementById('table_' + testId); tableElem.insertRow(1); var newRow = tableElem.rows[1]; if (hidden) { newRow.style.display = 'none'; } var changeStatus = (result.delta) ? 'broken' : 'fixed'; var className = 'verification'; className += result.delta ? ('-changed-' + changeStatus) : ''; newRow.className = className; var time = result.startTime && result.finishtime ? ' [' + (result.finishtime - result.startTime) + ' ms] ' : ''; var actualValue = (typeof(result.actual) == 'object') ? Helper.getString(result.actual) : result.actual; var expectedValue = (typeof(result.expected) == 'object') ? Helper.getString(result.expected) : result.expected; var entry = []; entry.push(''); entry.push(''); entry.push(''); entry.push('[' + result.id + '] '); entry.push(result.name); entry.push(': '); entry.push('' + Result.severity.getString(result.severity) + ''); if (result.delta) { entry.push('[CHANGED FROM LAST RUN]'); } entry.push(time); entry.push(': '); entry.push('(got \''); entry.push(actualValue); entry.push('\')'); if (result.severity > Result.severity.PASS) { entry.push(', expected \''); entry.push(expectedValue); entry.push('\''); } entry.push(''); newRow.innerHTML = entry.join(''); }; /** * Updates test summary table for the test suite and gadget * @param {ResultGroup} result of the test */ HtmlLogger.prototype.updateSuiteSummary = function(result) { var resultText; if (result.severity == Result.severity.UNVERIFIED) { resultText = Result.severity.getString(result.severity).substr(0, 3); } else { resultText = Result.severity.getString(result.severity).substr(0, 4); } var total = 0; var found = false; var failCount = 0; var passCount = 0; var unvCount = 0; var warnCount = 0; for (var i = 0; i < this.testSuiteDirectory.suites.length; i++) { var suite = this.testSuiteDirectory.suites[i]; var resultElem = document.getElementById(suite.id + '_' + resultText); var suiteTotalElem = document.getElementById(suite.id + '_TOT'); var suiteTotal = 0; for (var j = 0; j < suite.tests.length; j++) { if (suite.tests[j].id == result.test.id) { var resCount = parseInt(resultElem.innerHTML, 10); resultElem.innerHTML = ++resCount; suiteTotal = parseInt(suiteTotalElem.innerHTML, 10); suiteTotalElem.innerHTML = ++suiteTotal; found = true; break; } else if (found) { break; } } // calculate counts for final summary var counterElem = document.getElementById(suite.id + '_PASS'); passCount += parseInt(counterElem.innerHTML); counterElem = document.getElementById(suite.id + '_FAIL'); failCount += parseInt(counterElem.innerHTML); counterElem = document.getElementById(suite.id + '_WARN'); warnCount += parseInt(counterElem.innerHTML); counterElem = document.getElementById(suite.id + '_UNV'); unvCount += parseInt(counterElem.innerHTML); total += parseInt(suiteTotalElem.innerHTML); } // Update final summary; var counterLocation = document.getElementById('TOTAL_PASS'); counterLocation.innerHTML = passCount; counterLocation = document.getElementById('TOTAL_FAIL'); counterLocation.innerHTML = failCount; counterLocation = document.getElementById('TOTAL_WARN'); counterLocation.innerHTML = warnCount; counterLocation = document.getElementById('TOTAL_UNV'); counterLocation.innerHTML = unvCount; counterLocation = document.getElementById('TOTAL_TOT'); counterLocation.innerHTML = total; }; /** * Updates the priority table with the details of priority tests. * @param {Array} priorityFailInfo information of failed cases on per * priority basis * @param {status} status of the test execution */ HtmlLogger.prototype.updatePriorityTable = function(priorityFailInfo, status) { var priorityDescription = {}; priorityDescription[Test.PRIORITY.P4] = 'Visual cosmetic bugs. Or something like that. Lowest priority bug.' + 'You can fix when you have nothing else to do.'; priorityDescription[Test.PRIORITY.P3] = 'But that causes some irritation but you can live with it most of the' + ' time.'; priorityDescription[Test.PRIORITY.P2] = 'Functional nice to have breaks. i.e Exceptions for undefined behavior'; priorityDescription[Test.PRIORITY.P1] = 'Important bugs not exactly falling in the P0s. But have negative impact'; priorityDescription[Test.PRIORITY.P0] = 'You are not doing something stated in the spec. You are not spec' + ' compliant'; var prioritySummary = document.getElementById('priority-summary'); for (var priority in priorityFailInfo) { if (priorityFailInfo[priority].length > 0) { var priorityDesc = []; for (var i = 0; i < priorityFailInfo[priority].length; ++i) { priorityDesc.push(priorityFailInfo[priority][i].name + ' :: ' + priorityFailInfo[priority][i].id); } prioritySummary.insertRow(0); var row = prioritySummary.rows[0]; row.innerHTML = ' ' + priority + ' ' + '' + priorityDescription[priority] + '' + '' + priorityFailInfo[priority].length + '' + priorityDesc.join('
') + ''; } } if (prioritySummary.rows.length > 0) { prioritySummary.insertRow(0); var row = prioritySummary.rows[0]; row.innerHTML = 'Priority' + 'Description' + 'Failures' + 'Info'; prioritySummary.className = status; } var priorityInfoDiv = document.getElementById('priority-fail-info'); priorityInfoDiv.innerHTML = gadgets.json.stringify(priorityFailInfo); }; /** * Adds error links for failed, unverified and warning results for each * suite. It will also make sure that suite button caption is correct. * * @param {Array.} resultSets array of resultSets each resultSet * maps to testSuite in a directory */ HtmlLogger.prototype.updateSuitesHeader = function(resultSets) { var suiteResult = 0; for (var i = 0; i < resultSets.length; i++) { var id = resultSets[i].id; var failText = ''; var warnText = ''; var unvText = ''; var warn = 0; var unv = 0; var fail = 0; for (var j = 0; j < resultSets[i].results.length; j++) { var result = resultSets[i].results[j]; switch(result.severity) { case Result.severity.UNVERIFIED: unvText += '' + result.test.id + ', '; unv++; break; case Result.severity.FAIL: var link = '' + result.test.id + ', ' failText += link; fail++; this.priorityFailInfo[ result.test.priority ? result.test.priority : Test.PRIORITY.P2 ].push({ name: resultSets[i].name, id: result.id }); break; case Result.severity.WARNING: warnText += '' + result.test.id + ', '; warn++; break; } } suiteResult = (fail > 0) ? 3 : (warn > 0) ? 2 : (unv > 0) ? 1 : 0; if (suiteResult > this.summaryResult) { this.summaryResult = suiteResult; } var suiteTitle = document.getElementById(id + '_title'); suiteTitle.className = this.statusClassName[suiteResult]; var suiteTable = document.getElementById(id + '_table'); suiteTable.className = this.statusClassName[suiteResult]; var elem = document.getElementById(id + '_error_links'); elem.innerHTML = (fail ? 'Failed: ' + failText : '') + (warn ? '
Warnings: ' + warnText : '') + (unv ? '
Unverifieds: ' + unvText : ''); } }; /** * Updates main summary table after all tests are run * * @param {Array.} resultSets array of resultSets each resultSet * maps to testSuite in a directory */ HtmlLogger.prototype.updateSummaryHeader = function(resultSets) { this.updatePriorityTable(this.priorityFailInfo, this.statusClassName[this.summaryResult]); if (resultSets.length == 1) { var suite_summary_row = document.getElementById(resultSets[0].id + '_summary_row'); suite_summary_row.style.display = 'none'; } var summary = document.getElementById('summary'); summary.className = 'gadget-' + this.statusClassName[this.summaryResult]; var summaryTable = document.getElementById('TOTAL_table'); summaryTable.className = this.statusClassName[this.summaryResult]; var executionStatus = document.getElementById('execution-status'); if (this.testSuiteDirectory.suites.length === 1) { executionStatus.innerHTML = ''; } else { executionStatus.innerHTML = 'Finished'; executionStatus.className = ''; } }; /** * Will convert results in simple Array and puts it in jason box for you to save * it as golden results. Golden results will be used as benchmark for later * test results. * @param {Array.} resultSets The array of resultSets * @param {Object} goldenResults Jason representation of results */ HtmlLogger.prototype.updateResultBoxes = function(resultSets, goldenResults, context) { // golden results hidden box var goldenBoxHidden = document.getElementById('testArea'); goldenBoxHidden.innerHTML = Helper.getString( Helper.convertResultsToMapExcludeVerifications(resultSets)); HtmlLoggerUtils.setResultCollection(resultSets); // visible golden results var goldenBoxVisible = document.getElementById('goldenArea'); goldenBoxVisible.innerHTML = Helper.stringify(goldenResults); XmlLoggerUtils.setResultSet(resultSets); XmlLoggerUtils.setContainer(testRunner.getContext().getContainer().name); XmlLoggerUtils.setContext(context); var elem = document.getElementById('xml-link'); elem.style.display = "inline"; if (self.gadgets && gadgets.window && gadgets.window.adjustHeight) { // Do this only if dynamic height is supported. This is useful when it's // run inside the orkut container, for example. gadgets.window.adjustHeight(); } }; /** * HtmlLoggerUtils namespace. * This namespace holds many functions to aid the generated HTML from the * HtmlLogger class, contains methods to collapse/expand results, store result * json information for external calls, and handlers for the buttons generated * by the HtmlLogger. */ var HtmlLoggerUtils = function() {}; /** Text for collapse all button displayed at suite summary level */ HtmlLoggerUtils.COLLAPSE_ALL_TEXT = 'Collapse all sub results'; /** Text for expand all button displayed at suite summary level */ HtmlLoggerUtils.EXPAND_ALL_TEXT = 'Expand all sub results'; /** * Toggles the visibility of the sub-results of a single result in result table, * changes the text of the button that triggered this action * (parameter 'element') and finally if possible adjusts * the height of the gadget.
* This function searches for the parent table container of each result then * for every TR inside other than the result header, will change it display * property to 'none' or 'table-row' as necessary.
* Additionally at the end of the function if gadgets.window.adjustHeight * function is available it will be called to readjust the height of the gadget. * @param {Element} element The button that triggered the collapse/expand event. */ HtmlLoggerUtils.toggleHideSubResult = function(element) { // Change the button value accordingly if (element.tagName == 'INPUT') { if (element.value == 'Collapse') { element.value = 'Expand'; } else { element.value = 'Collapse'; } } var displayStyle; if (element.value == 'Expand') { displayStyle = 'none'; } else { displayStyle = 'table-row'; } // Find the table container while (element.tagName != 'TABLE') { element = element.parentNode; } // Find the contained elements to be hidden (the inner table) var tables = element.getElementsByTagName('TR'); for (var i = 0; tables && i < tables.length; i++) { if (tables[i].className == 'verification') { tables[i].style.display = displayStyle; } } if (self.gadgets && gadgets.window && gadgets.window.adjustHeight) { // Do this only if dynamic height is supported. This is useful when it's // run inside the orkut container, for example. gadgets.window.adjustHeight(); } }; /** * Toggles the visibility of the sub-results for all tests in a suite, * changes the text of the button that triggered this action * (parameter 'element') and finally if possible adjusts the height of the * gadget.
* This function searches for the parent row container of all results then * for every INPUT element in that row container, will check if it needs to be * toggled and call HtmlLoggerUtils.toggleHideSubResults.
* Additionally at the end of the function if gadgets.window.adjustHeight * function is available it will be called to readjust the height of the gadget. * @param {Element} element The button that triggered the collapse/expand event. */ HtmlLoggerUtils.toggleHideAllSubResults = function(element) { // Change the button value accordingly if (element.tagName == 'INPUT') { if (element.value == HtmlLoggerUtils.COLLAPSE_ALL_TEXT) { element.value = HtmlLoggerUtils.EXPAND_ALL_TEXT; } else { element.value = HtmlLoggerUtils.COLLAPSE_ALL_TEXT; } } var caption = element.value; // Find the table container while (element.tagName != 'TR' || element.className != 'test-summary') { element = element.parentNode; } // Find the contained elements to be hidden (the inner table) var inputs = element.getElementsByTagName('INPUT'); for (var i = 0; inputs && i < inputs.length; i++) { if (inputs[i].value == 'Expand' && caption == HtmlLoggerUtils.COLLAPSE_ALL_TEXT) { HtmlLoggerUtils.toggleHideSubResult(inputs[i]); } else if (inputs[i].value == 'Collapse' && caption == HtmlLoggerUtils.EXPAND_ALL_TEXT) { HtmlLoggerUtils.toggleHideSubResult(inputs[i]); } } if (self.gadgets && gadgets.window && gadgets.window.adjustHeight) { // Do this only if dynamic height is supported. This is useful when it's // run inside the orkut container, for example. gadgets.window.adjustHeight(); } }; /** * Toggles the visibility of results for all tests in a suite. It hides/shows * detailis of results of suite. It also toggles the name of the button that * triggered this action (parameter 'element') and finally if possible adjusts * the height of the gadget.
* This function searches for the parent table container for suite then * for every TR with class name 'test-summary', will change its display * property to 'none' or 'table-row' as necessary.
* Additionally at the end of the function if gadgets.window.adjustHeight * function is available it will be called to readjust the height of the gadget. * @param {Element} element The button that triggered the collapse/expand event. */ HtmlLoggerUtils.toggleHideTestSuiteResults = function(element) { // Change the button value accordingly if (element.tagName == 'INPUT') { if (element.value == 'Collapse') { element.value = 'Expand'; } else { element.value = 'Collapse'; } } // Find the table container while (element.tagName != 'TABLE' || element.className != 'suitesummary') { element = element.parentNode; } // Find the contained elements to be hidden (the inner table) var tables = element.getElementsByTagName('TR'); for (var i = 0; tables && i < tables.length; i++) { if (tables[i].className == 'test-summary') { if (tables[i].style.display == 'none') { tables[i].style.display = 'table-row'; } else { tables[i].style.display = 'none'; } } } if (self.gadgets && gadgets.window && gadgets.window.adjustHeight) { // Do this only if dynamic height is supported. This is useful when it's // run inside the orkut container, for example. gadgets.window.adjustHeight(); } }; /** * Toggles the visibility of details of all test suites. It hides/shows details * of results of all suites. It also toggles the name of the button that * triggered this action (parameter 'element') and finally if possible adjusts * the height of the gadget.
* This function finds all elements with class name 'suitesummary', * will change display property to 'none' or 'table-row' as necessary for all * matching elements.
* Additionally at the end of the function if gadgets.window.adjustHeight * function is available it will be called to readjust the height of the gadget. * @param {Element} element The button that triggered the collapse/expand event. */ HtmlLoggerUtils.toggleHideTestSuites = function(element) { // Change the button value accordingly if (element.tagName == 'INPUT') { if (element.value == 'Collapse') { element.value = 'Expand'; } else { element.value = 'Collapse'; } } // Find the contained elements to be hidden (the inner table) var tables = document.getElementsByTagName('TABLE'); for (var i = 0; tables && i < tables.length; i++) { if (tables[i].className == 'suitesummary') { if (tables[i].style.display == 'none') { tables[i].style.display = 'table-row'; } else { tables[i].style.display = 'none'; } } } if (self.gadgets && gadgets.window && gadgets.window.adjustHeight) { // Do this only if dynamic height is supported. This is useful when it's // run inside the orkut container, for example. gadgets.window.adjustHeight(); } }; /** * Stores the results for external static access. * @type {Array.} */ HtmlLoggerUtils.resultCollection_ = []; /** * Gets the results stored in the static context, this usually happens when the * logger renders its output. * @return {Array.} An array with the results inside. */ HtmlLoggerUtils.getResultCollection = function() { return HtmlLoggerUtils.resultCollection_; }; /** * Gets a JSON representation of the results stored in this static context.
* Note: for this function to work correctly the function gadgets.json.stringify * must be defined and work correctly. * @return {string} A json representation of the results stored in this static * context. */ HtmlLoggerUtils.getResultJson = function() { return gadgets.json.stringify(HtmlLoggerUtils.resultCollection_); }; /** * Stores the results array in this static context.
* This function is usually called by the HtmlLogger when the output is * displayed. * @param {Array.} results The results to store in this static context. */ HtmlLoggerUtils.setResultCollection = function(results) { HtmlLoggerUtils.resultCollection_ = results; }; /** * Saves the golden results inside a given TEXTAREA with the specified id. * Note that the TEXTAREA will be searched inside in the parent of the element * so it is important that both the element and the TEXTAREA to seek are at the * same DOM hierarchy level. * @param {Element} element The button that triggered the action. * @param {string} suiteId The suite id. * @param {string} elementId The id of the TEXTAREA that contains the golden * results */ HtmlLoggerUtils.saveGoldenResults = function(element, suiteId, elementId) { element.disabled = true; var goldenContainer = document.getElementById(elementId); if (goldenContainer) { var goldenResults = gadgets.json.parse(goldenContainer.value); Helper.saveGoldenResults(suiteId, goldenResults, function () { element.disabled = false; }); } };