mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
4a5d9b03f8
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@39001 467b73ca-7a2a-4603-9d3b-597d59a354a9
743 lines
22 KiB
JavaScript
Executable File
743 lines
22 KiB
JavaScript
Executable File
/*
|
|
* Copyright 2004 ThoughtWorks, Inc
|
|
*
|
|
* 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.
|
|
*
|
|
*/
|
|
|
|
// The current row in the list of tests (test suite)
|
|
currentRowInSuite = 0;
|
|
|
|
// An object representing the current test
|
|
currentTest = null;
|
|
|
|
// Whether or not the jsFT should run all tests in the suite
|
|
runAllTests = false;
|
|
|
|
// Whether or not the current test has any errors;
|
|
testFailed = false;
|
|
suiteFailed = false;
|
|
|
|
// Colors used to provide feedback
|
|
passColor = "#ccffcc";
|
|
doneColor = "#eeffee";
|
|
failColor = "#ffcccc";
|
|
workingColor = "#ffffcc";
|
|
|
|
// Holds the handlers for each command.
|
|
commandHandlers = null;
|
|
|
|
// The number of tests run
|
|
numTestPasses = 0;
|
|
|
|
// The number of tests that have failed
|
|
numTestFailures = 0;
|
|
|
|
// The number of commands which have passed
|
|
numCommandPasses = 0;
|
|
|
|
// The number of commands which have failed
|
|
numCommandFailures = 0;
|
|
|
|
// The number of commands which have caused errors (element not found)
|
|
numCommandErrors = 0;
|
|
|
|
// The time that the test was started.
|
|
startTime = null;
|
|
|
|
// The current time.
|
|
currentTime = null;
|
|
|
|
// An simple enum for failureType
|
|
ERROR = 0;
|
|
FAILURE = 1;
|
|
|
|
runInterval = 0;
|
|
|
|
queryString = null;
|
|
|
|
function setRunInterval() {
|
|
// Get the value of the checked runMode option.
|
|
// There should be a way of getting the value of the "group", but I don't know how.
|
|
var runModeOptions = document.forms['controlPanel'].runMode;
|
|
for (var i = 0; i < runModeOptions.length; i++) {
|
|
if (runModeOptions[i].checked) {
|
|
runInterval = runModeOptions[i].value;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
function continueCurrentTest() {
|
|
document.getElementById('continueTest').disabled = true;
|
|
testLoop.resume();
|
|
}
|
|
|
|
function getApplicationFrame() {
|
|
return document.getElementById('myiframe');
|
|
}
|
|
|
|
function getSuiteFrame() {
|
|
return document.getElementById('testSuiteFrame');
|
|
}
|
|
|
|
function getTestFrame(){
|
|
return document.getElementById('testFrame');
|
|
}
|
|
|
|
function loadAndRunIfAuto() {
|
|
loadSuiteFrame();
|
|
}
|
|
|
|
function start() {
|
|
queryString = null;
|
|
setRunInterval();
|
|
loadSuiteFrame();
|
|
}
|
|
|
|
function loadSuiteFrame() {
|
|
var testAppFrame = document.getElementById('myiframe');
|
|
selenium = Selenium.createForFrame(testAppFrame);
|
|
registerCommandHandlers();
|
|
|
|
//set the runInterval if there is a queryParameter for it
|
|
var tempRunInterval = getQueryParameter("runInterval");
|
|
if (tempRunInterval) {
|
|
runInterval = tempRunInterval;
|
|
}
|
|
|
|
document.getElementById("modeRun").onclick = setRunInterval;
|
|
document.getElementById('modeWalk').onclick = setRunInterval;
|
|
document.getElementById('modeStep').onclick = setRunInterval;
|
|
document.getElementById('continueTest').onclick = continueCurrentTest;
|
|
|
|
var testSuiteName = getQueryParameter("test");
|
|
|
|
if (testSuiteName) {
|
|
addLoadListener(getSuiteFrame(), onloadTestSuite);
|
|
getSuiteFrame().src = testSuiteName;
|
|
} else {
|
|
onloadTestSuite();
|
|
}
|
|
}
|
|
|
|
function startSingleTest() {
|
|
removeLoadListener(getApplicationFrame(), startSingleTest);
|
|
var singleTestName = getQueryParameter("singletest");
|
|
addLoadListener(getTestFrame(), startTest);
|
|
getTestFrame().src = singleTestName;
|
|
}
|
|
|
|
function getIframeDocument(iframe)
|
|
{
|
|
if (iframe.contentDocument) {
|
|
return iframe.contentDocument;
|
|
}
|
|
else {
|
|
return iframe.contentWindow.document;
|
|
}
|
|
}
|
|
|
|
function onloadTestSuite() {
|
|
removeLoadListener(getSuiteFrame(), onloadTestSuite);
|
|
|
|
// Add an onclick function to each link in all suite tables
|
|
var allTables = getIframeDocument(getSuiteFrame()).getElementsByTagName("table");
|
|
for (var tableNum = 0; tableNum < allTables.length; tableNum++)
|
|
{
|
|
var skippedTable = allTables[tableNum];
|
|
for(rowNum = 1;rowNum < skippedTable.rows.length; rowNum++) {
|
|
addOnclick(skippedTable, rowNum);
|
|
}
|
|
}
|
|
|
|
suiteTable = getIframeDocument(getSuiteFrame()).getElementsByTagName("table")[0];
|
|
if (suiteTable!=null) {
|
|
|
|
if (isAutomatedRun()) {
|
|
startTestSuite();
|
|
} else if (getQueryParameter("autoURL")) {
|
|
|
|
addLoadListener(getApplicationFrame(), startSingleTest);
|
|
|
|
getApplicationFrame().src = getQueryParameter("autoURL");
|
|
|
|
} else {
|
|
testLink = suiteTable.rows[currentRowInSuite+1].cells[0].getElementsByTagName("a")[0];
|
|
getTestFrame().src = testLink.href;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Adds an onclick function to the link in the given row in suite table.
|
|
// This function checks whether the test has already been run and the data is
|
|
// stored. If the data is stored, it sets the test frame to be the stored data.
|
|
// Otherwise, it loads the fresh page.
|
|
function addOnclick(suiteTable, rowNum) {
|
|
aLink = suiteTable.rows[rowNum].cells[0].getElementsByTagName("a")[0];
|
|
aLink.onclick = function(eventObj) {
|
|
srcObj = null;
|
|
|
|
// For mozilla-like browsers
|
|
if(eventObj)
|
|
srcObj = eventObj.target;
|
|
|
|
// For IE-like browsers
|
|
else if (getSuiteFrame().contentWindow.event)
|
|
srcObj = getSuiteFrame().contentWindow.event.srcElement;
|
|
|
|
// The target row (the event source is not consistently reported by browsers)
|
|
row = srcObj.parentNode.parentNode.rowIndex || srcObj.parentNode.parentNode.parentNode.rowIndex;
|
|
|
|
// If the row has a stored results table, use that
|
|
if(suiteTable.rows[row].cells[1]) {
|
|
var bodyElement = getIframeDocument(getTestFrame()).body;
|
|
|
|
// Create a div element to hold the results table.
|
|
var tableNode = getIframeDocument(getTestFrame()).createElement("div");
|
|
var resultsCell = suiteTable.rows[row].cells[1];
|
|
tableNode.innerHTML = resultsCell.innerHTML;
|
|
|
|
// Append this text node, and remove all the preceding nodes.
|
|
bodyElement.appendChild(tableNode);
|
|
while (bodyElement.firstChild != bodyElement.lastChild) {
|
|
bodyElement.removeChild(bodyElement.firstChild);
|
|
}
|
|
}
|
|
// Otherwise, just open up the fresh page.
|
|
else {
|
|
getTestFrame().src = suiteTable.rows[row].cells[0].getElementsByTagName("a")[0].href;
|
|
}
|
|
|
|
return false;
|
|
};
|
|
}
|
|
|
|
function isQueryParameterTrue(name) {
|
|
parameterValue = getQueryParameter(name);
|
|
return (parameterValue != null && parameterValue.toLowerCase() == "true");
|
|
}
|
|
|
|
function getQueryString() {
|
|
if (queryString != null) return queryString;
|
|
if (browserVersion.isHTA) {
|
|
var args = extractArgs();
|
|
if (args.length < 2) return null;
|
|
queryString = args[1];
|
|
return queryString;
|
|
} else {
|
|
return location.search.substr(1);
|
|
}
|
|
}
|
|
|
|
function extractArgs() {
|
|
var str = SeleniumHTARunner.commandLine;
|
|
if (str == null || str == "") return new Array();
|
|
var matches = str.match(/(?:"([^"]+)"|(?!"([^"]+)")\b(\S+)\b)/g);
|
|
// We either want non quote stuff ([^"]+) surrounded by quotes
|
|
// or we want to look-ahead, see that the next character isn't
|
|
// a quoted argument, and then grab all the non-space stuff
|
|
// this will return for the line: "foo" bar
|
|
// the results "\"foo\"" and "bar"
|
|
|
|
// So, let's unquote the quoted arguments:
|
|
var args = new Array;
|
|
for (var i = 0; i < matches.length; i++) {
|
|
args[i] = matches[i];
|
|
args[i] = args[i].replace(/^"(.*)"$/, "$1");
|
|
}
|
|
return args;
|
|
}
|
|
|
|
function getQueryParameter(searchKey) {
|
|
var str = getQueryString();
|
|
if (str == null) return null;
|
|
var clauses = str.split('&');
|
|
for (var i = 0; i < clauses.length; i++) {
|
|
var keyValuePair = clauses[i].split('=',2);
|
|
var key = unescape(keyValuePair[0]);
|
|
if (key == searchKey) {
|
|
return unescape(keyValuePair[1]);
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
function isNewWindow() {
|
|
return isQueryParameterTrue("newWindow");
|
|
}
|
|
|
|
function isAutomatedRun() {
|
|
return isQueryParameterTrue("auto");
|
|
}
|
|
|
|
function resetMetrics() {
|
|
numTestPasses = 0;
|
|
numTestFailures = 0;
|
|
numCommandPasses = 0;
|
|
numCommandFailures = 0;
|
|
numCommandErrors = 0;
|
|
startTime = new Date().getTime();
|
|
}
|
|
|
|
function runSingleTest() {
|
|
runAllTests = false;
|
|
resetMetrics();
|
|
startTest();
|
|
}
|
|
|
|
function startTest() {
|
|
removeLoadListener(getTestFrame(), startTest);
|
|
|
|
// Scroll to the top of the test frame
|
|
if (getTestFrame().contentWindow) {
|
|
getTestFrame().contentWindow.scrollTo(0,0);
|
|
}
|
|
else {
|
|
frames['testFrame'].scrollTo(0,0);
|
|
}
|
|
|
|
currentTest = new HtmlTest(getIframeDocument(getTestFrame()));
|
|
|
|
testFailed = false;
|
|
storedVars = new Object();
|
|
|
|
testLoop = initialiseTestLoop();
|
|
testLoop.start();
|
|
}
|
|
|
|
function HtmlTest(testDocument) {
|
|
this.init(testDocument);
|
|
}
|
|
|
|
HtmlTest.prototype = {
|
|
|
|
init: function(testDocument) {
|
|
this.document = testDocument;
|
|
this.document.bgColor = "";
|
|
this.currentRow = null;
|
|
this.commandRows = new Array();
|
|
this.headerRow = null;
|
|
var tables = this.document.getElementsByTagName("table");
|
|
for (var i = 0; i < tables.length; i++) {
|
|
var candidateRows = tables[i].rows;
|
|
for (var j = 0; j < candidateRows.length; j++) {
|
|
if (!this.headerRow) {
|
|
this.headerRow = candidateRows[j];
|
|
}
|
|
if (candidateRows[j].cells.length >= 3) {
|
|
this.addCommandRow(candidateRows[j]);
|
|
}
|
|
}
|
|
}
|
|
},
|
|
|
|
addCommandRow: function(row) {
|
|
if (row.cells[2] && row.cells[2].originalHTML) {
|
|
row.cells[2].innerHTML = row.cells[2].originalHTML;
|
|
}
|
|
row.bgColor = "";
|
|
this.commandRows.push(row);
|
|
},
|
|
|
|
nextCommand: function() {
|
|
if (this.commandRows.length > 0) {
|
|
this.currentRow = this.commandRows.shift();
|
|
} else {
|
|
this.currentRow = null;
|
|
}
|
|
return this.currentRow;
|
|
}
|
|
|
|
};
|
|
|
|
function startTestSuite() {
|
|
resetMetrics();
|
|
currentRowInSuite = 0;
|
|
runAllTests = true;
|
|
suiteFailed = false;
|
|
|
|
runNextTest();
|
|
}
|
|
|
|
function runNextTest() {
|
|
if (!runAllTests)
|
|
return;
|
|
|
|
suiteTable = getIframeDocument(getSuiteFrame()).getElementsByTagName("table")[0];
|
|
|
|
// Do not change the row color of the first row
|
|
if (currentRowInSuite > 0) {
|
|
// Provide test-status feedback
|
|
if (testFailed) {
|
|
setCellColor(suiteTable.rows, currentRowInSuite, 0, failColor);
|
|
} else {
|
|
setCellColor(suiteTable.rows, currentRowInSuite, 0, passColor);
|
|
}
|
|
|
|
// Set the results from the previous test run
|
|
setResultsData(suiteTable, currentRowInSuite);
|
|
}
|
|
|
|
currentRowInSuite++;
|
|
|
|
// If we are done with all of the tests, set the title bar as pass or fail
|
|
if (currentRowInSuite >= suiteTable.rows.length) {
|
|
if (suiteFailed) {
|
|
setCellColor(suiteTable.rows, 0, 0, failColor);
|
|
} else {
|
|
setCellColor(suiteTable.rows, 0, 0, passColor);
|
|
}
|
|
|
|
// If this is an automated run (i.e., build script), then submit
|
|
// the test results by posting to a form
|
|
if (isAutomatedRun())
|
|
postTestResults(suiteFailed, suiteTable);
|
|
}
|
|
|
|
else {
|
|
// Make the current row blue
|
|
setCellColor(suiteTable.rows, currentRowInSuite, 0, workingColor);
|
|
|
|
testLink = suiteTable.rows[currentRowInSuite].cells[0].getElementsByTagName("a")[0];
|
|
testLink.focus();
|
|
|
|
var testFrame = getTestFrame();
|
|
addLoadListener(testFrame, startTest);
|
|
|
|
selenium.browserbot.setIFrameLocation(testFrame, testLink.href);
|
|
}
|
|
}
|
|
|
|
function setCellColor(tableRows, row, col, colorStr) {
|
|
tableRows[row].cells[col].bgColor = colorStr;
|
|
}
|
|
|
|
// Sets the results from a test into a hidden column on the suite table. So,
|
|
// for each tests, the second column is set to the HTML from the test table.
|
|
function setResultsData(suiteTable, row) {
|
|
// Create a text node of the test table
|
|
var resultTable = getIframeDocument(getTestFrame()).body.innerHTML;
|
|
if (!resultTable) return;
|
|
|
|
var tableNode = suiteTable.ownerDocument.createElement("div");
|
|
tableNode.innerHTML = resultTable;
|
|
|
|
var new_column = suiteTable.ownerDocument.createElement("td");
|
|
new_column.appendChild(tableNode);
|
|
|
|
// Set the column to be invisible
|
|
new_column.style.cssText = "display: none;";
|
|
|
|
// Add the invisible column
|
|
suiteTable.rows[row].appendChild(new_column);
|
|
}
|
|
|
|
// Post the results to a servlet, CGI-script, etc. The URL of the
|
|
// results-handler defaults to "/postResults", but an alternative location
|
|
// can be specified by providing a "resultsUrl" query parameter.
|
|
//
|
|
// Parameters passed to the results-handler are:
|
|
// result: passed/failed depending on whether the suite passed or failed
|
|
// totalTime: the total running time in seconds for the suite.
|
|
//
|
|
// numTestPasses: the total number of tests which passed.
|
|
// numTestFailures: the total number of tests which failed.
|
|
//
|
|
// numCommandPasses: the total number of commands which passed.
|
|
// numCommandFailures: the total number of commands which failed.
|
|
// numCommandErrors: the total number of commands which errored.
|
|
//
|
|
// suite: the suite table, including the hidden column of test results
|
|
// testTable.1 to testTable.N: the individual test tables
|
|
//
|
|
function postTestResults(suiteFailed, suiteTable) {
|
|
|
|
form = document.createElement("form");
|
|
document.body.appendChild(form);
|
|
|
|
form.id = "resultsForm";
|
|
form.method="post";
|
|
form.target="myiframe";
|
|
|
|
var resultsUrl = getQueryParameter("resultsUrl");
|
|
if (!resultsUrl) {
|
|
resultsUrl = "./postResults";
|
|
}
|
|
|
|
var actionAndParameters = resultsUrl.split('?',2);
|
|
form.action = actionAndParameters[0];
|
|
var resultsUrlQueryString = actionAndParameters[1];
|
|
|
|
form.createHiddenField = function(name, value) {
|
|
input = document.createElement("input");
|
|
input.type = "hidden";
|
|
input.name = name;
|
|
input.value = value;
|
|
this.appendChild(input);
|
|
};
|
|
|
|
if (resultsUrlQueryString) {
|
|
var clauses = resultsUrlQueryString.split('&');
|
|
for (var i = 0; i < clauses.length; i++) {
|
|
var keyValuePair = clauses[i].split('=',2);
|
|
var key = unescape(keyValuePair[0]);
|
|
var value = unescape(keyValuePair[1]);
|
|
form.createHiddenField(key, value);
|
|
}
|
|
}
|
|
|
|
form.createHiddenField("selenium.version", Selenium.version);
|
|
form.createHiddenField("selenium.revision", Selenium.revision);
|
|
|
|
form.createHiddenField("result", suiteFailed == true ? "failed" : "passed");
|
|
|
|
form.createHiddenField("totalTime", Math.floor((currentTime - startTime) / 1000));
|
|
form.createHiddenField("numTestPasses", numTestPasses);
|
|
form.createHiddenField("numTestFailures", numTestFailures);
|
|
form.createHiddenField("numCommandPasses", numCommandPasses);
|
|
form.createHiddenField("numCommandFailures", numCommandFailures);
|
|
form.createHiddenField("numCommandErrors", numCommandErrors);
|
|
|
|
// Create an input for each test table. The inputs are named
|
|
// testTable.1, testTable.2, etc.
|
|
for (rowNum = 1; rowNum < suiteTable.rows.length;rowNum++) {
|
|
// If there is a second column, then add a new input
|
|
if (suiteTable.rows[rowNum].cells.length > 1) {
|
|
var resultCell = suiteTable.rows[rowNum].cells[1];
|
|
form.createHiddenField("testTable." + rowNum, resultCell.innerHTML);
|
|
// remove the resultCell, so it's not included in the suite HTML
|
|
resultCell.parentNode.removeChild(resultCell);
|
|
}
|
|
}
|
|
|
|
form.createHiddenField("numTestTotal", rowNum);
|
|
|
|
// Add HTML for the suite itself
|
|
form.createHiddenField("suite", suiteTable.parentNode.innerHTML);
|
|
|
|
if (isQueryParameterTrue("save")) {
|
|
saveToFile(resultsUrl, form);
|
|
} else {
|
|
form.submit();
|
|
}
|
|
document.body.removeChild(form);
|
|
if (isQueryParameterTrue("close")) {
|
|
window.top.close();
|
|
}
|
|
}
|
|
|
|
function saveToFile(fileName, form) {
|
|
// This only works when run as an IE HTA
|
|
var inputs = new Object();
|
|
for (var i = 0; i < form.elements.length; i++) {
|
|
inputs[form.elements[i].name] = form.elements[i].value;
|
|
}
|
|
var objFSO = new ActiveXObject("Scripting.FileSystemObject")
|
|
var scriptFile = objFSO.CreateTextFile(fileName);
|
|
scriptFile.WriteLine("<html><body>\n<h1>Test suite results </h1>" +
|
|
"\n\n<table>\n<tr>\n<td>result:</td>\n<td>" + inputs["result"] + "</td>\n" +
|
|
"</tr>\n<tr>\n<td>totalTime:</td>\n<td>" + inputs["totalTime"] + "</td>\n</tr>\n" +
|
|
"<tr>\n<td>numTestPasses:</td>\n<td>" + inputs["numTestPasses"] + "</td>\n</tr>\n" +
|
|
"<tr>\n<td>numTestFailures:</td>\n<td>" + inputs["numTestFailures"] + "</td>\n</tr>\n" +
|
|
"<tr>\n<td>numCommandPasses:</td>\n<td>" + inputs["numCommandPasses"] + "</td>\n</tr>\n" +
|
|
"<tr>\n<td>numCommandFailures:</td>\n<td>" + inputs["numCommandFailures"] + "</td>\n</tr>\n" +
|
|
"<tr>\n<td>numCommandErrors:</td>\n<td>" + inputs["numCommandErrors"] + "</td>\n</tr>\n" +
|
|
"<tr>\n<td>" + inputs["suite"] + "</td>\n<td> </td>\n</tr>");
|
|
var testNum = inputs["numTestTotal"];
|
|
for (var rowNum = 1; rowNum < testNum; rowNum++) {
|
|
scriptFile.WriteLine("<tr>\n<td>" + inputs["testTable." + rowNum] + "</td>\n<td> </td>\n</tr>");
|
|
}
|
|
scriptFile.WriteLine("</table></body></html>");
|
|
scriptFile.Close();
|
|
}
|
|
|
|
function printMetrics() {
|
|
setText(document.getElementById("commandPasses"), numCommandPasses);
|
|
setText(document.getElementById("commandFailures"), numCommandFailures);
|
|
setText(document.getElementById("commandErrors"), numCommandErrors);
|
|
setText(document.getElementById("testRuns"), numTestPasses + numTestFailures);
|
|
setText(document.getElementById("testFailures"), numTestFailures);
|
|
|
|
currentTime = new Date().getTime();
|
|
|
|
timeDiff = currentTime - startTime;
|
|
totalSecs = Math.floor(timeDiff / 1000);
|
|
|
|
minutes = Math.floor(totalSecs / 60);
|
|
seconds = totalSecs % 60;
|
|
|
|
setText(document.getElementById("elapsedTime"), pad(minutes)+":"+pad(seconds));
|
|
}
|
|
|
|
// Puts a leading 0 on num if it is less than 10
|
|
function pad (num) {
|
|
return (num > 9) ? num : "0" + num;
|
|
}
|
|
|
|
/*
|
|
* Register all of the built-in command handlers with the CommandHandlerFactory.
|
|
* TODO work out an easy way for people to register handlers without modifying the Selenium sources.
|
|
*/
|
|
function registerCommandHandlers() {
|
|
commandFactory = new CommandHandlerFactory();
|
|
commandFactory.registerAll(selenium);
|
|
|
|
}
|
|
|
|
function initialiseTestLoop() {
|
|
testLoop = new TestLoop(commandFactory);
|
|
|
|
testLoop.getCommandInterval = function() { return runInterval; };
|
|
testLoop.nextCommand = nextCommand;
|
|
testLoop.commandStarted = commandStarted;
|
|
testLoop.commandComplete = commandComplete;
|
|
testLoop.commandError = commandError;
|
|
testLoop.testComplete = testComplete;
|
|
testLoop.pause = function() {
|
|
document.getElementById('continueTest').disabled = false;
|
|
};
|
|
return testLoop;
|
|
}
|
|
|
|
function nextCommand() {
|
|
var row = currentTest.nextCommand();
|
|
if (row == null) {
|
|
return null;
|
|
}
|
|
row.cells[2].originalHTML = row.cells[2].innerHTML;
|
|
return new SeleniumCommand(getText(row.cells[0]),
|
|
getText(row.cells[1]),
|
|
getText(row.cells[2]));
|
|
}
|
|
|
|
function removeNbsp(value) {
|
|
return value.replace(/\240/g, "");
|
|
}
|
|
|
|
function scrollIntoView(element) {
|
|
if (element.scrollIntoView) {
|
|
element.scrollIntoView(false);
|
|
return;
|
|
}
|
|
// TODO: work out how to scroll browsers that don't support
|
|
// scrollIntoView (like Konqueror)
|
|
}
|
|
|
|
function commandStarted() {
|
|
currentTest.currentRow.bgColor = workingColor;
|
|
scrollIntoView(currentTest.currentRow.cells[0]);
|
|
printMetrics();
|
|
}
|
|
|
|
function commandComplete(result) {
|
|
if (result.failed) {
|
|
numCommandFailures += 1;
|
|
recordFailure(result.failureMessage);
|
|
} else if (result.passed) {
|
|
numCommandPasses += 1;
|
|
currentTest.currentRow.bgColor = passColor;
|
|
} else {
|
|
currentTest.currentRow.bgColor = doneColor;
|
|
}
|
|
}
|
|
|
|
function commandError(errorMessage) {
|
|
numCommandErrors += 1;
|
|
recordFailure(errorMessage);
|
|
}
|
|
|
|
function recordFailure(errorMsg) {
|
|
LOG.warn("recordFailure: " + errorMsg);
|
|
// Set cell background to red
|
|
currentTest.currentRow.bgColor = failColor;
|
|
|
|
// Set error message
|
|
currentTest.currentRow.cells[2].innerHTML = errorMsg;
|
|
currentTest.currentRow.title = errorMsg;
|
|
testFailed = true;
|
|
suiteFailed = true;
|
|
}
|
|
|
|
function testComplete() {
|
|
var resultColor = passColor;
|
|
if (testFailed) {
|
|
resultColor = failColor;
|
|
numTestFailures += 1;
|
|
} else {
|
|
numTestPasses += 1;
|
|
}
|
|
|
|
if (currentTest.headerRow) {
|
|
currentTest.headerRow.bgColor = resultColor;
|
|
}
|
|
|
|
printMetrics();
|
|
|
|
window.setTimeout("runNextTest()", 1);
|
|
}
|
|
|
|
Selenium.prototype.doPause = function(waitTime) {
|
|
testLoop.pauseInterval = waitTime;
|
|
};
|
|
|
|
Selenium.prototype.doBreak = function() {
|
|
document.getElementById('modeStep').checked = true;
|
|
runInterval = -1;
|
|
};
|
|
|
|
/*
|
|
* Click on the located element, and attach a callback to notify
|
|
* when the page is reloaded.
|
|
*/
|
|
Selenium.prototype.doModalDialogTest = function(returnValue) {
|
|
this.browserbot.doModalDialogTest(returnValue);
|
|
};
|
|
|
|
/*
|
|
* Store the value of a form input in a variable
|
|
*/
|
|
Selenium.prototype.doStoreValue = function(target, varName) {
|
|
if (!varName) {
|
|
// Backward compatibility mode: read the ENTIRE text of the page
|
|
// and stores it in a variable with the name of the target
|
|
value = this.page().bodyText();
|
|
storedVars[target] = value;
|
|
return;
|
|
}
|
|
var element = this.page().findElement(target);
|
|
storedVars[varName] = getInputValue(element);
|
|
};
|
|
|
|
/*
|
|
* Store the text of an element in a variable
|
|
*/
|
|
Selenium.prototype.doStoreText = function(target, varName) {
|
|
var element = this.page().findElement(target);
|
|
storedVars[varName] = getText(element);
|
|
};
|
|
|
|
/*
|
|
* Store the value of an element attribute in a variable
|
|
*/
|
|
Selenium.prototype.doStoreAttribute = function(target, varName) {
|
|
storedVars[varName] = this.page().findAttribute(target);
|
|
};
|
|
|
|
/*
|
|
* Store the result of a literal value
|
|
*/
|
|
Selenium.prototype.doStore = function(value, varName) {
|
|
storedVars[varName] = value;
|
|
};
|