summaryrefslogtreecommitdiff
path: root/tests/test_tools/selenium/core/scripts/selenium-testrunner.js
diff options
context:
space:
mode:
authorxue <>2007-03-26 00:27:59 +0000
committerxue <>2007-03-26 00:27:59 +0000
commit0f00e85e311955b3f84dde559da6b5a2ab5c3cda (patch)
treeccb93c4e2d056c69209307fcb680fc23a9c57370 /tests/test_tools/selenium/core/scripts/selenium-testrunner.js
parentcbee2945d1858f7f256b44a3fbfe816dc0202f4d (diff)
merge from 3.0 branch till 1769.
Diffstat (limited to 'tests/test_tools/selenium/core/scripts/selenium-testrunner.js')
-rw-r--r--tests/test_tools/selenium/core/scripts/selenium-testrunner.js516
1 files changed, 301 insertions, 215 deletions
diff --git a/tests/test_tools/selenium/core/scripts/selenium-testrunner.js b/tests/test_tools/selenium/core/scripts/selenium-testrunner.js
index b5104d39..fd7f2076 100644
--- a/tests/test_tools/selenium/core/scripts/selenium-testrunner.js
+++ b/tests/test_tools/selenium/core/scripts/selenium-testrunner.js
@@ -20,36 +20,55 @@ var currentTest = null; // TODO: get rid of this global, which mirrors the htmlT
var selenium = null;
var htmlTestRunner;
-var HtmlTestRunner = Class.create();
-Object.extend(HtmlTestRunner.prototype, {
+var HtmlTestRunner = classCreate();
+objectExtend(HtmlTestRunner.prototype, {
initialize: function() {
this.metrics = new Metrics();
this.controlPanel = new HtmlTestRunnerControlPanel();
- this.htmlTestSuite = null;
this.testFailed = false;
this.currentTest = null;
this.runAllTests = false;
this.appWindow = null;
// we use a timeout here to make sure the LOG has loaded first, so we can see _every_ error
- setTimeout(function() {
+ setTimeout(fnBind(function() {
this.loadSuiteFrame();
- }.bind(this), 500);
+ }, this), 500);
+ },
+
+ getTestSuite: function() {
+ return suiteFrame.getCurrentTestSuite();
},
markFailed: function() {
this.testFailed = true;
- this.htmlTestSuite.markFailed();
+ this.getTestSuite().markFailed();
},
loadSuiteFrame: function() {
if (selenium == null) {
- selenium = Selenium.createForWindow(this._getApplicationWindow());
+ var appWindow = this._getApplicationWindow();
+ try { appWindow.location; }
+ catch (e) {
+ // when reloading, we may be pointing at an old window (Perm Denied)
+ setTimeout(fnBind(function() {
+ this.loadSuiteFrame();
+ }, this), 50);
+ return;
+ }
+ selenium = Selenium.createForWindow(appWindow);
this._registerCommandHandlers();
}
this.controlPanel.setHighlightOption();
var testSuiteName = this.controlPanel.getTestSuiteName();
+ var self = this;
if (testSuiteName) {
- suiteFrame.load(testSuiteName, this._onloadTestSuite.bind(this));
+ suiteFrame.load(testSuiteName, function() {setTimeout(fnBind(self._onloadTestSuite, self), 50)} );
+ selenium.browserbot.baseUrl = absolutify(testSuiteName, window.location.href);
+ }
+ // DGF or should we use the old default?
+ // selenium.browserbot.baseUrl = window.location.href;
+ if (this.controlPanel.getBaseUrl()) {
+ selenium.browserbot.baseUrl = this.controlPanel.getBaseUrl();
}
},
@@ -62,31 +81,30 @@ Object.extend(HtmlTestRunner.prototype, {
_getSeparateApplicationWindow: function () {
if (this.appWindow == null) {
- this.appWindow = openSeparateApplicationWindow('TestRunner-splash.html');
+ this.appWindow = openSeparateApplicationWindow('TestRunner-splash.html', this.controlPanel.isAutomatedRun());
}
return this.appWindow;
},
_onloadTestSuite:function () {
- this.htmlTestSuite = new HtmlTestSuite(suiteFrame.getDocument());
- if (! this.htmlTestSuite.isAvailable()) {
+ if (! this.getTestSuite().isAvailable()) {
return;
}
if (this.controlPanel.isAutomatedRun()) {
- htmlTestRunner.startTestSuite();
+ this.startTestSuite();
} else if (this.controlPanel.getAutoUrl()) {
//todo what is the autourl doing, left to check it out
- addLoadListener(this._getApplicationWindow(), this._startSingleTest.bind(this));
+ addLoadListener(this._getApplicationWindow(), fnBind(this._startSingleTest, this));
this._getApplicationWindow().src = this.controlPanel.getAutoUrl();
} else {
- this.htmlTestSuite.getSuiteRows()[0].loadTestCase();
+ this.getTestSuite().getSuiteRows()[0].loadTestCase();
}
},
_startSingleTest:function () {
- removeLoadListener(getApplicationWindow(), this._startSingleTest.bind(this));
+ removeLoadListener(getApplicationWindow(), fnBind(this._startSingleTest, this));
var singleTestName = this.controlPanel.getSingleTestName();
- testFrame.load(singleTestName, this.startTest.bind(this));
+ testFrame.load(singleTestName, fnBind(this.startTest, this));
},
_registerCommandHandlers: function () {
@@ -97,16 +115,17 @@ Object.extend(HtmlTestRunner.prototype, {
startTestSuite: function() {
this.controlPanel.reset();
this.metrics.resetMetrics();
- this.htmlTestSuite.reset();
+ this.getTestSuite().reset();
this.runAllTests = true;
this.runNextTest();
},
runNextTest: function () {
+ this.getTestSuite().updateSuiteWithResultOfPreviousTest();
if (!this.runAllTests) {
return;
}
- this.htmlTestSuite.runNextTestInSuite();
+ this.getTestSuite().runNextTestInSuite();
},
startTest: function () {
@@ -127,26 +146,15 @@ Object.extend(HtmlTestRunner.prototype, {
}
});
-var FeedbackColors = Class.create();
-Object.extend(FeedbackColors, {
- passColor : "#ccffcc",
- doneColor : "#eeffee",
- failColor : "#ffcccc",
- workingColor : "#ffffcc",
- breakpointColor : "#cccccc"
-});
-
-
var runInterval = 0;
-
/** SeleniumFrame encapsulates an iframe element */
-var SeleniumFrame = Class.create();
-Object.extend(SeleniumFrame.prototype, {
+var SeleniumFrame = classCreate();
+objectExtend(SeleniumFrame.prototype, {
initialize : function(frame) {
this.frame = frame;
- addLoadListener(this.frame, this._handleLoad.bind(this));
+ addLoadListener(this.frame, fnBind(this._handleLoad, this));
},
getDocument : function() {
@@ -154,13 +162,38 @@ Object.extend(SeleniumFrame.prototype, {
},
_handleLoad: function() {
- this._onLoad();
+ this._attachStylesheet();
+ this._onLoad();
if (this.loadCallback) {
this.loadCallback();
this.loadCallback = null;
}
},
+ _attachStylesheet: function() {
+ var d = this.getDocument();
+ var head = d.getElementsByTagName('head').item(0);
+ var styleLink = d.createElement("link");
+ styleLink.rel = "stylesheet";
+ styleLink.type = "text/css";
+ if (browserVersion && browserVersion.isChrome) {
+ // DGF We have to play a clever trick to get the right absolute path.
+ // This trick works on most browsers, (not IE), but is only needed in
+ // chrome
+ var tempLink = window.document.createElement("link");
+ tempLink.href = "selenium-test.css"; // this will become an absolute href
+ styleLink.href = tempLink.href;
+ } else {
+ // this works in every browser (except Firefox in chrome mode)
+ var styleSheetPath = window.location.pathname.replace(/[^\/\\]+$/, "selenium-test.css");
+ if (browserVersion.isIE && window.location.protocol == "file:") {
+ styleSheetPath = "file://" + styleSheetPath;
+ }
+ styleLink.href = styleSheetPath;
+ }
+ head.appendChild(styleLink);
+ },
+
_onLoad: function() {
},
@@ -169,10 +202,14 @@ Object.extend(SeleniumFrame.prototype, {
},
_setLocation: function(location) {
+ var isChrome = browserVersion.isChrome || false;
+ var isHTA = browserVersion.isHTA || false;
+ // DGF TODO multiWindow
+ location += "?thisIsChrome=" + isChrome + "&thisIsHTA=" + isHTA;
if (browserVersion.isSafari) {
- // safari doesn't reload the page when the location equals to current location.
- // hence, set the location to blank so that the page will reload automatically.
- this.frame.src = "about:blank";
+ // safari doesn't reload the page when the location equals to current location.
+ // hence, set the location to blank so that the page will reload automatically.
+ this.frame.src = "about:blank";
this.frame.src = location;
} else {
this.frame.contentWindow.location.replace(location);
@@ -189,18 +226,27 @@ Object.extend(SeleniumFrame.prototype, {
});
+/** HtmlTestSuiteFrame - encapsulates the suite iframe element */
+var HtmlTestSuiteFrame = classCreate();
+objectExtend(HtmlTestSuiteFrame.prototype, SeleniumFrame.prototype);
+objectExtend(HtmlTestSuiteFrame.prototype, {
+
+ getCurrentTestSuite: function() {
+ if (!this.currentTestSuite) {
+ this.currentTestSuite = new HtmlTestSuite(this.getDocument());
+ }
+ return this.currentTestSuite;
+ }
+
+});
+
/** HtmlTestFrame - encapsulates the test-case iframe element */
-var HtmlTestFrame = Class.create();
-Object.extend(HtmlTestFrame.prototype, SeleniumFrame.prototype);
-Object.extend(HtmlTestFrame.prototype, {
+var HtmlTestFrame = classCreate();
+objectExtend(HtmlTestFrame.prototype, SeleniumFrame.prototype);
+objectExtend(HtmlTestFrame.prototype, {
_onLoad: function() {
- this.setCurrentTestCase();
- },
-
- setCurrentTestCase: function() {
- //todo: this is not good looking
- this.currentTestCase = new HtmlTestCase(this.getDocument(), htmlTestRunner.htmlTestSuite.getCurrentRow());
+ this.currentTestCase = new HtmlTestCase(this.getDocument(), htmlTestRunner.getTestSuite().getCurrentRow());
},
getCurrentTestCase: function() {
@@ -210,14 +256,14 @@ Object.extend(HtmlTestFrame.prototype, {
});
function onSeleniumLoad() {
- suiteFrame = new SeleniumFrame(getSuiteFrame());
+ suiteFrame = new HtmlTestSuiteFrame(getSuiteFrame());
testFrame = new HtmlTestFrame(getTestFrame());
htmlTestRunner = new HtmlTestRunner();
}
-
var suiteFrame;
var testFrame;
+
function getSuiteFrame() {
var f = $('testSuiteFrame');
if (f == null) {
@@ -236,9 +282,9 @@ function getTestFrame() {
return f;
}
-var HtmlTestRunnerControlPanel = Class.create();
-Object.extend(HtmlTestRunnerControlPanel.prototype, URLConfiguration.prototype);
-Object.extend(HtmlTestRunnerControlPanel.prototype, {
+var HtmlTestRunnerControlPanel = classCreate();
+objectExtend(HtmlTestRunnerControlPanel.prototype, URLConfiguration.prototype);
+objectExtend(HtmlTestRunnerControlPanel.prototype, {
initialize: function() {
this._acquireQueryString();
@@ -248,16 +294,17 @@ Object.extend(HtmlTestRunnerControlPanel.prototype, {
this.pauseButton = $('pauseTest');
this.stepButton = $('stepTest');
- this.highlightOption.onclick = (function() {
+ this.highlightOption.onclick = fnBindAsEventListener((function() {
this.setHighlightOption();
- }).bindAsEventListener(this);
- this.pauseButton.onclick = this.pauseCurrentTest.bindAsEventListener(this);
- this.stepButton.onclick = this.stepCurrentTest.bindAsEventListener(this);
+ }), this);
+ this.pauseButton.onclick = fnBindAsEventListener(this.pauseCurrentTest, this);
+ this.stepButton.onclick = fnBindAsEventListener(this.stepCurrentTest, this);
+
this.speedController = new Control.Slider('speedHandle', 'speedTrack', {
range: $R(0, 1000),
- onSlide: this.setRunInterval.bindAsEventListener(this),
- onChange: this.setRunInterval.bindAsEventListener(this)
+ onSlide: fnBindAsEventListener(this.setRunInterval, this),
+ onChange: fnBindAsEventListener(this.setRunInterval, this)
});
this._parseQueryParameter();
@@ -265,7 +312,7 @@ Object.extend(HtmlTestRunnerControlPanel.prototype, {
setHighlightOption: function () {
var isHighlight = this.highlightOption.checked;
- selenium.browserbot.getCurrentPage().setHighlightElement(isHighlight);
+ selenium.browserbot.setShouldHighlightElement(isHighlight);
},
_parseQueryParameter: function() {
@@ -295,19 +342,19 @@ Object.extend(HtmlTestRunnerControlPanel.prototype, {
},
reset: function() {
- this.runInterval = this.speedController.value;
+ // this.runInterval = this.speedController.value;
this._switchContinueButtonToPause();
},
_switchContinueButtonToPause: function() {
- this.pauseButton.innerHTML = "Pause";
- this.pauseButton.onclick = this.pauseCurrentTest.bindAsEventListener(this);
+ this.pauseButton.className = "cssPauseTest";
+ this.pauseButton.onclick = fnBindAsEventListener(this.pauseCurrentTest, this);
},
_switchPauseButtonToContinue: function() {
$('stepTest').disabled = false;
- this.pauseButton.innerHTML = "Continue";
- this.pauseButton.onclick = this.continueCurrentTest.bindAsEventListener(this);
+ this.pauseButton.className = "cssContinueTest";
+ this.pauseButton.onclick = fnBindAsEventListener(this.continueCurrentTest, this);
},
stepCurrentTest: function () {
@@ -356,36 +403,58 @@ Object.extend(HtmlTestRunnerControlPanel.prototype, {
});
-
-var AbstractResultAwareRow = Class.create();
-Object.extend(AbstractResultAwareRow.prototype, {
+var AbstractResultAwareRow = classCreate();
+objectExtend(AbstractResultAwareRow.prototype, {
initialize: function(trElement) {
this.trElement = trElement;
},
- markWorking: function() {
- this.trElement.bgColor = FeedbackColors.workingColor;
+ setStatus: function(status) {
+ this.unselect();
+ this.trElement.className = this.trElement.className.replace(/status_[a-z]+/, "");
+ if (status) {
+ addClassName(this.trElement, "status_" + status);
+ }
+ },
+
+ select: function() {
+ addClassName(this.trElement, "selected");
safeScrollIntoView(this.trElement);
},
+ unselect: function() {
+ removeClassName(this.trElement, "selected");
+ },
+
markPassed: function() {
- this.trElement.bgColor = FeedbackColors.passColor;
+ this.setStatus("passed");
},
markDone: function() {
- this.trElement.bgColor = FeedbackColors.doneColor;
+ this.setStatus("done");
},
markFailed: function() {
- this.trElement.bgColor = FeedbackColors.failColor;
+ this.setStatus("failed");
+ }
+
+});
+
+var TitleRow = classCreate();
+objectExtend(TitleRow.prototype, AbstractResultAwareRow.prototype);
+objectExtend(TitleRow.prototype, {
+
+ initialize: function(trElement) {
+ this.trElement = trElement;
+ trElement.className = "title";
}
});
-var HtmlTestCaseRow = Class.create();
-Object.extend(HtmlTestCaseRow.prototype, AbstractResultAwareRow.prototype);
-Object.extend(HtmlTestCaseRow.prototype, {
+var HtmlTestCaseRow = classCreate();
+objectExtend(HtmlTestCaseRow.prototype, AbstractResultAwareRow.prototype);
+objectExtend(HtmlTestCaseRow.prototype, {
getCommand: function () {
return new SeleniumCommand(getText(this.trElement.cells[0]),
@@ -395,16 +464,16 @@ Object.extend(HtmlTestCaseRow.prototype, {
},
markFailed: function(errorMsg) {
- this.trElement.bgColor = FeedbackColors.failColor;
+ AbstractResultAwareRow.prototype.markFailed.call(this, errorMsg);
this.setMessage(errorMsg);
},
setMessage: function(message) {
- this.trElement.cells[2].innerHTML = message;
+ setText(this.trElement.cells[2], message);
},
reset: function() {
- this.trElement.bgColor = '';
+ this.setStatus(null);
var thirdCell = this.trElement.cells[2];
if (thirdCell) {
if (thirdCell.originalHTML) {
@@ -418,19 +487,18 @@ Object.extend(HtmlTestCaseRow.prototype, {
onClick: function() {
if (this.trElement.isBreakpoint == undefined) {
this.trElement.isBreakpoint = true;
- this.trElement.beforeBackgroundColor = Element.getStyle(this.trElement, "backgroundColor");
- Element.setStyle(this.trElement, {"background-color" : FeedbackColors.breakpointColor});
+ addClassName(this.trElement, "breakpoint");
} else {
this.trElement.isBreakpoint = undefined;
- Element.setStyle(this.trElement, {"background-color" : this.trElement.beforeBackgroundColor});
+ removeClassName(this.trElement, "breakpoint");
}
},
addBreakpointSupport: function() {
- Element.setStyle(this.trElement, {"cursor" : "pointer"});
- this.trElement.onclick = function() {
+ elementSetStyle(this.trElement, {"cursor" : "pointer"});
+ this.trElement.onclick = fnBindAsEventListener(function() {
this.onClick();
- }.bindAsEventListener(this);
+ }, this);
},
isBreakpoint: function() {
@@ -441,42 +509,44 @@ Object.extend(HtmlTestCaseRow.prototype, {
}
});
-var HtmlTestSuiteRow = Class.create();
-Object.extend(HtmlTestSuiteRow.prototype, AbstractResultAwareRow.prototype);
-Object.extend(HtmlTestSuiteRow.prototype, {
+var HtmlTestSuiteRow = classCreate();
+objectExtend(HtmlTestSuiteRow.prototype, AbstractResultAwareRow.prototype);
+objectExtend(HtmlTestSuiteRow.prototype, {
initialize: function(trElement, testFrame, htmlTestSuite) {
this.trElement = trElement;
this.testFrame = testFrame;
this.htmlTestSuite = htmlTestSuite;
this.link = trElement.getElementsByTagName("a")[0];
- this.link.onclick = this._onClick.bindAsEventListener(this);
+ this.link.onclick = fnBindAsEventListener(this._onClick, this);
},
reset: function() {
- this.trElement.bgColor = '';
+ this.setStatus(null);
},
_onClick: function() {
- // todo: just send a message to the testSuite
this.loadTestCase(null);
return false;
},
loadTestCase: function(onloadFunction) {
+ this.htmlTestSuite.unselectCurrentRow();
+ this.select();
this.htmlTestSuite.currentRowInSuite = this.trElement.rowIndex - 1;
// If the row has a stored results table, use that
var resultsFromPreviousRun = this.trElement.cells[1];
if (resultsFromPreviousRun) {
- // this.testFrame.restoreTestCase(resultsFromPreviousRun.innerHTML);
+ // todo: delegate to TestFrame, e.g.
+ // this.testFrame.restoreTestCase(resultsFromPreviousRun.innerHTML);
var testBody = this.testFrame.getDocument().body;
testBody.innerHTML = resultsFromPreviousRun.innerHTML;
- testFrame.setCurrentTestCase();
+ this.testFrame._onLoad();
if (onloadFunction) {
onloadFunction();
}
} else {
- this.testFrame.load(this.link.href, onloadFunction);
+ this.testFrame.load(this.link.href, onloadFunction);
}
},
@@ -498,28 +568,24 @@ Object.extend(HtmlTestSuiteRow.prototype, {
});
-var HtmlTestSuite = Class.create();
-Object.extend(HtmlTestSuite.prototype, {
+var HtmlTestSuite = classCreate();
+objectExtend(HtmlTestSuite.prototype, {
initialize: function(suiteDocument) {
this.suiteDocument = suiteDocument;
this.suiteRows = this._collectSuiteRows();
- this.titleRow = this.getTestTable().rows[0];
- this.title = this.titleRow.cells[0].innerHTML;
+ this.titleRow = new TitleRow(this.getTestTable().rows[0]);
this.reset();
},
reset: function() {
this.failed = false;
this.currentRowInSuite = -1;
- this.titleRow.bgColor = '';
- this.suiteRows.each(function(row) {
+ this.titleRow.setStatus(null);
+ for (var i = 0; i < this.suiteRows.length; i++) {
+ var row = this.suiteRows[i];
row.reset();
- });
- },
-
- getTitle: function() {
- return this.title;
+ }
},
getSuiteRows: function() {
@@ -537,31 +603,51 @@ Object.extend(HtmlTestSuite.prototype, {
_collectSuiteRows: function () {
var result = [];
- for (rowNum = 1; rowNum < this.getTestTable().rows.length; rowNum++) {
- var rowElement = this.getTestTable().rows[rowNum];
+ var tables = $A(this.suiteDocument.getElementsByTagName("table"));
+ var testTable = tables[0];
+ for (rowNum = 1; rowNum < testTable.rows.length; rowNum++) {
+ var rowElement = testTable.rows[rowNum];
result.push(new HtmlTestSuiteRow(rowElement, testFrame, this));
}
+
+ // process the unsuited rows as well
+ for (var tableNum = 1; tableNum < $A(this.suiteDocument.getElementsByTagName("table")).length; tableNum++) {
+ testTable = tables[tableNum];
+ for (rowNum = 1; rowNum < testTable.rows.length; rowNum++) {
+ var rowElement = testTable.rows[rowNum];
+ new HtmlTestSuiteRow(rowElement, testFrame, this);
+ }
+ }
return result;
},
getCurrentRow: function() {
+ if (this.currentRowInSuite == -1) {
+ return null;
+ }
return this.suiteRows[this.currentRowInSuite];
},
+ unselectCurrentRow: function() {
+ var currentRow = this.getCurrentRow()
+ if (currentRow) {
+ currentRow.unselect();
+ }
+ },
+
markFailed: function() {
this.failed = true;
- this.titleRow.bgColor = FeedbackColors.failColor;
+ this.titleRow.markFailed();
},
markDone: function() {
if (!this.failed) {
- this.titleRow.bgColor = FeedbackColors.passColor;
+ this.titleRow.markPassed();
}
},
_startCurrentTestCase: function() {
- this.getCurrentRow().markWorking();
- this.getCurrentRow().loadTestCase(htmlTestRunner.startTest.bind(htmlTestRunner));
+ this.getCurrentRow().loadTestCase(fnBind(htmlTestRunner.startTest, htmlTestRunner));
},
_onTestSuiteComplete: function() {
@@ -569,14 +655,13 @@ Object.extend(HtmlTestSuite.prototype, {
new TestResult(this.failed, this.getTestTable()).post();
},
- _updateSuiteWithResultOfPreviousTest: function() {
+ updateSuiteWithResultOfPreviousTest: function() {
if (this.currentRowInSuite >= 0) {
this.getCurrentRow().saveTestResults();
}
},
runNextTestInSuite: function() {
- this._updateSuiteWithResultOfPreviousTest();
this.currentRowInSuite++;
// If we are done with all of the tests, set the title bar as pass or fail
@@ -591,8 +676,8 @@ Object.extend(HtmlTestSuite.prototype, {
});
-var TestResult = Class.create();
-Object.extend(TestResult.prototype, {
+var TestResult = classCreate();
+objectExtend(TestResult.prototype, {
// Post the results to a servlet, CGI-script, etc. The URL of the
// results-handler defaults to "/postResults", but an alternative location
@@ -724,8 +809,8 @@ Object.extend(TestResult.prototype, {
});
/** HtmlTestCase encapsulates an HTML test document */
-var HtmlTestCase = Class.create();
-Object.extend(HtmlTestCase.prototype, {
+var HtmlTestCase = classCreate();
+objectExtend(HtmlTestCase.prototype, {
initialize: function(testDocument, htmlTestSuiteRow) {
if (testDocument == null) {
@@ -736,6 +821,7 @@ Object.extend(HtmlTestCase.prototype, {
}
this.testDocument = testDocument;
this.htmlTestSuiteRow = htmlTestSuiteRow;
+ this.headerRow = new TitleRow(this.testDocument.getElementsByTagName("tr")[0]);
this.commandRows = this._collectCommandRows();
this.nextCommandRowIndex = 0;
this._addBreakpointSupport();
@@ -745,13 +831,16 @@ Object.extend(HtmlTestCase.prototype, {
var commandRows = [];
var tables = $A(this.testDocument.getElementsByTagName("table"));
var self = this;
- tables.each(function (table) {
- $A(table.rows).each(function(candidateRow) {
+ for (var i = 0; i < tables.length; i++) {
+ var table = tables[i];
+ var tableRows = $A(table.rows);
+ for (var j = 0; j < tableRows.length; j++) {
+ var candidateRow = tableRows[j];
if (self.isCommandRow(candidateRow)) {
commandRows.push(new HtmlTestCaseRow(candidateRow));
}
- }.bind(this));
- });
+ }
+ }
return commandRows;
},
@@ -765,15 +854,16 @@ Object.extend(HtmlTestCase.prototype, {
*/
this.nextCommandRowIndex = 0;
- this._setTitleColor('');
- this.commandRows.each(function(row) {
+ this.setStatus('');
+ for (var i = 0; i < this.commandRows.length; i++) {
+ var row = this.commandRows[i];
row.reset();
- });
+ }
// remove any additional fake "error" row added to the end of the document
var errorElement = this.testDocument.getElementById('error');
if (errorElement) {
- Element.remove(errorElement);
+ errorElement.parentNode.removeChild(errorElement);
}
},
@@ -781,39 +871,38 @@ Object.extend(HtmlTestCase.prototype, {
return this.commandRows;
},
- _setTitleColor: function(color) {
- var headerRow = this.testDocument.getElementsByTagName("tr")[0];
- if (headerRow) {
- headerRow.bgColor = color;
- }
+ setStatus: function(status) {
+ this.headerRow.setStatus(status);
},
markFailed: function() {
- this._setTitleColor(FeedbackColors.failColor);
+ this.setStatus("failed");
this.htmlTestSuiteRow.markFailed();
},
markPassed: function() {
- this._setTitleColor(FeedbackColors.passColor);
+ this.setStatus("passed");
this.htmlTestSuiteRow.markPassed();
},
addErrorMessage: function(errorMsg, currentRow) {
+ errorMsg = errorMsg.replace(/ /g, String.fromCharCode(160)).replace("\n", '\\n');
if (currentRow) {
currentRow.markFailed(errorMsg);
} else {
var errorElement = this.testDocument.createElement("p");
errorElement.id = "error";
- errorElement.innerHTML = errorMsg;
+ setText(errorElement, errorMsg);
this.testDocument.body.appendChild(errorElement);
- Element.setStyle(errorElement, {'backgroundColor': FeedbackColors.failColor});
+ errorElement.className = "status_failed";
}
},
_addBreakpointSupport: function() {
- this.commandRows.each(function(row) {
+ for (var i = 0; i < this.commandRows.length; i++) {
+ var row = this.commandRows[i];
row.addBreakpointSupport();
- });
+ }
},
hasMoreCommandRows: function() {
@@ -850,8 +939,8 @@ var get_new_rows = function() {
};
-var Metrics = Class.create();
-Object.extend(Metrics.prototype, {
+var Metrics = classCreate();
+objectExtend(Metrics.prototype, {
initialize: function() {
// The number of tests run
this.numTestPasses = 0;
@@ -903,20 +992,13 @@ Object.extend(Metrics.prototype, {
});
-var HtmlRunnerCommandFactory = Class.create();
-Object.extend(HtmlRunnerCommandFactory.prototype, {
+var HtmlRunnerCommandFactory = classCreate();
+objectExtend(HtmlRunnerCommandFactory.prototype, {
initialize: function(seleniumCommandFactory, testLoop) {
this.seleniumCommandFactory = seleniumCommandFactory;
this.testLoop = testLoop;
- this.handlers = {
- pause: {
- execute: function(selenium, command) {
- testLoop.pauseInterval = command.target;
- return {};
- }
- }
- };
+ this.handlers = {};
//todo: register commands
},
@@ -929,9 +1011,9 @@ Object.extend(HtmlRunnerCommandFactory.prototype, {
});
-var HtmlRunnerTestLoop = Class.create();
-Object.extend(HtmlRunnerTestLoop.prototype, new TestLoop());
-Object.extend(HtmlRunnerTestLoop.prototype, {
+var HtmlRunnerTestLoop = classCreate();
+objectExtend(HtmlRunnerTestLoop.prototype, new TestLoop());
+objectExtend(HtmlRunnerTestLoop.prototype, {
initialize: function(htmlTestCase, metrics, seleniumCommandFactory) {
this.commandFactory = new HtmlRunnerCommandFactory(seleniumCommandFactory, this);
@@ -948,6 +1030,8 @@ Object.extend(HtmlRunnerTestLoop.prototype, {
// used for selenium tests in javascript
this.currentItem = null;
this.commandAgenda = new Array();
+ this.expectedFailure = null;
+ this.expectedFailureType = null;
this.htmlTestCase.reset();
@@ -986,11 +1070,12 @@ Object.extend(HtmlRunnerTestLoop.prototype, {
commandStarted : function() {
$('pauseTest').disabled = false;
- this.currentRow.markWorking();
+ this.currentRow.select();
this.metrics.printMetrics();
},
commandComplete : function(result) {
+ this._checkExpectedFailure(result);
if (result.failed) {
this.metrics.numCommandFailures += 1;
this._recordFailure(result.failureMessage);
@@ -1002,7 +1087,49 @@ Object.extend(HtmlRunnerTestLoop.prototype, {
}
},
+ _checkExpectedFailure : function(result) {
+ if (this.expectedFailure != null) {
+ if (this.expectedFailureJustSet) {
+ this.expectedFailureJustSet = false;
+ return;
+ }
+ if (!result.failed) {
+ result.passed = false;
+ result.failed = true;
+ result.failureMessage = "Expected " + this.expectedFailureType + " did not occur.";
+ } else {
+ if (PatternMatcher.matches(this.expectedFailure, result.failureMessage)) {
+ var failureType = result.error ? "error" : "failure";
+ if (failureType == this.expectedFailureType) {
+ result.failed = false;
+ result.passed = true;
+ } else {
+ result.failed = true;
+ result.failureMessage = "Expected "+this.expectedFailureType+", but "+failureType+" occurred instead";
+ }
+ } else {
+ result.failed = true;
+ result.failureMessage = "Expected " + this.expectedFailureType + " message '" + this.expectedFailure
+ + "' but was '" + result.failureMessage + "'";
+ }
+ }
+ this.expectedFailure = null;
+ this.expectedFailureType = null;
+ }
+ },
+
commandError : function(errorMessage) {
+ var tempResult = {};
+ tempResult.passed = false;
+ tempResult.failed = true;
+ tempResult.error = true;
+ tempResult.failureMessage = errorMessage;
+ this._checkExpectedFailure(tempResult);
+ if (tempResult.passed) {
+ this.currentRow.markDone();
+ return true;
+ }
+ errorMessage = tempResult.failureMessage;
this.metrics.numCommandErrors += 1;
this._recordFailure(errorMessage);
},
@@ -1062,6 +1189,13 @@ Object.extend(HtmlRunnerTestLoop.prototype, {
});
+Selenium.prototype.doPause = function(waitTime) {
+ /** Wait for the specified amount of time (in milliseconds)
+ * @param waitTime the amount of time to sleep (in milliseconds)
+ */
+ // todo: should not refer to currentTest directly
+ currentTest.pauseInterval = waitTime;
+};
Selenium.prototype.doBreak = function() {
/** Halt the currently running test, and wait for the user to press the Continue button.
@@ -1115,81 +1249,33 @@ Selenium.prototype.assertSelected = function(selectLocator, optionLocator) {
locator.assertSelected(element);
};
-/**
- * Tell Selenium to expect a failure on the next command execution. This
- * command temporarily installs a CommandFactory that generates
- * CommandHandlers that expect a failure.
- */
Selenium.prototype.assertFailureOnNext = function(message) {
+ /**
+ * Tell Selenium to expect a failure on the next command execution.
+ * @param message The failure message we should expect. This command will fail if the wrong failure message appears.
+ */
if (!message) {
- throw new Error("Message must be provided");
+ throw new SeleniumError("Message must be provided");
}
- var expectFailureCommandFactory =
- new ExpectFailureCommandFactory(currentTest.commandFactory, message, "failure", executeCommandAndReturnFailureMessage);
- currentTest.commandFactory = expectFailureCommandFactory;
+ currentTest.expectedFailure = message;
+ currentTest.expectedFailureType = "failure";
+ currentTest.expectedFailureJustSet = true;
};
-/**
- * Tell Selenium to expect an error on the next command execution. This
- * command temporarily installs a CommandFactory that generates
- * CommandHandlers that expect a failure.
- */
Selenium.prototype.assertErrorOnNext = function(message) {
+ /**
+ * Tell Selenium to expect an error on the next command execution.
+ * @param message The error message we should expect. This command will fail if the wrong error message appears.
+ */
+ // This command temporarily installs a CommandFactory that generates
+ // CommandHandlers that expect an error.
if (!message) {
- throw new Error("Message must be provided");
+ throw new SeleniumError("Message must be provided");
}
- var expectFailureCommandFactory =
- new ExpectFailureCommandFactory(currentTest.commandFactory, message, "error", executeCommandAndReturnErrorMessage);
- currentTest.commandFactory = expectFailureCommandFactory;
-};
-
-function executeCommandAndReturnFailureMessage(baseHandler, originalArguments) {
- var baseResult = baseHandler.execute.apply(baseHandler, originalArguments);
- if (baseResult.passed) {
- return null;
- }
- return baseResult.failureMessage;
-};
-
-function executeCommandAndReturnErrorMessage(baseHandler, originalArguments) {
- try {
- baseHandler.execute.apply(baseHandler, originalArguments);
- return null;
- }
- catch (expected) {
- return expected.message;
- }
+ currentTest.expectedFailure = message;
+ currentTest.expectedFailureType = "error";
+ currentTest.expectedFailureJustSet = true;
};
-function ExpectFailureCommandHandler(baseHandler, originalCommandFactory, expectedErrorMessage, errorType, decoratedExecutor) {
- this.execute = function() {
- var baseFailureMessage = decoratedExecutor(baseHandler, arguments);
- var result = {};
- if (!baseFailureMessage) {
- result.failed = true;
- result.failureMessage = "Expected " + errorType + " did not occur.";
- }
- else {
- if (! PatternMatcher.matches(expectedErrorMessage, baseFailureMessage)) {
- result.failed = true;
- result.failureMessage = "Expected " + errorType + " message '" + expectedErrorMessage
- + "' but was '" + baseFailureMessage + "'";
- }
- else {
- result.passed = true;
- result.result = baseFailureMessage;
- }
- }
- currentTest.commandFactory = originalCommandFactory;
- return result;
- };
-}
-
-function ExpectFailureCommandFactory(originalCommandFactory, expectedErrorMessage, errorType, decoratedExecutor) {
- this.getCommandHandler = function(name) {
- var baseHandler = originalCommandFactory.getCommandHandler(name);
- return new ExpectFailureCommandHandler(baseHandler, originalCommandFactory, expectedErrorMessage, errorType, decoratedExecutor);
- };
-};