diff options
Diffstat (limited to 'tests/test_tools/selenium/core/scripts/selenium-remoterunner.js')
-rw-r--r-- | tests/test_tools/selenium/core/scripts/selenium-remoterunner.js | 466 |
1 files changed, 466 insertions, 0 deletions
diff --git a/tests/test_tools/selenium/core/scripts/selenium-remoterunner.js b/tests/test_tools/selenium/core/scripts/selenium-remoterunner.js new file mode 100644 index 00000000..1c95c134 --- /dev/null +++ b/tests/test_tools/selenium/core/scripts/selenium-remoterunner.js @@ -0,0 +1,466 @@ +/* +* Copyright 2005 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. +* +*/ + +passColor = "#cfffcf"; +failColor = "#ffcfcf"; +errorColor = "#ffffff"; +workingColor = "#DEE7EC"; +doneColor = "#FFFFCC"; + +var injectedSessionId; +var cmd1 = document.createElement("div"); +var cmd2 = document.createElement("div"); +var cmd3 = document.createElement("div"); +var cmd4 = document.createElement("div"); + +var postResult = "START"; +var debugMode = false; +var relayToRC = null; +var proxyInjectionMode = false; +var uniqueId = 'sel_' + Math.round(100000 * Math.random()); + +var RemoteRunnerOptions = classCreate(); +objectExtend(RemoteRunnerOptions.prototype, URLConfiguration.prototype); +objectExtend(RemoteRunnerOptions.prototype, { + initialize: function() { + this._acquireQueryString(); + }, + isDebugMode: function() { + return this._isQueryParameterTrue("debugMode"); + }, + + getContinue: function() { + return this._getQueryParameter("continue"); + }, + + getDriverUrl: function() { + return this._getQueryParameter("driverUrl"); + }, + + getSessionId: function() { + return this._getQueryParameter("sessionId"); + }, + + _acquireQueryString: function () { + if (this.queryString) return; + if (browserVersion.isHTA) { + var args = this._extractArgs(); + if (args.length < 2) return null; + this.queryString = args[1]; + } else if (proxyInjectionMode) { + this.queryString = selenium.browserbot.getCurrentWindow().location.search.substr(1); + } else { + this.queryString = top.location.search.substr(1); + } + } + +}); +var runOptions; + +function runSeleniumTest() { + runOptions = new RemoteRunnerOptions(); + var testAppWindow; + + if (runOptions.isMultiWindowMode()) { + testAppWindow = openSeparateApplicationWindow('Blank.html', true); + } else if ($('myiframe') != null) { + var myiframe = $('myiframe'); + if (myiframe) { + testAppWindow = myiframe.contentWindow; + } + } + else { + proxyInjectionMode = true; + testAppWindow = window; + } + selenium = Selenium.createForWindow(testAppWindow, proxyInjectionMode); + if (runOptions.getBaseUrl()) { + selenium.browserbot.baseUrl = runOptions.getBaseUrl(); + } + if (!debugMode) { + debugMode = runOptions.isDebugMode(); + } + if (proxyInjectionMode) { + LOG.log = logToRc; + selenium.browserbot._modifyWindow(testAppWindow); + } + else if (debugMode) { + LOG.logHook = logToRc; + } + window.selenium = selenium; + + commandFactory = new CommandHandlerFactory(); + commandFactory.registerAll(selenium); + + currentTest = new RemoteRunner(commandFactory); + + if (document.getElementById("commandList") != null) { + document.getElementById("commandList").appendChild(cmd4); + document.getElementById("commandList").appendChild(cmd3); + document.getElementById("commandList").appendChild(cmd2); + document.getElementById("commandList").appendChild(cmd1); + } + + var doContinue = runOptions.getContinue(); + if (doContinue != null) postResult = "OK"; + + currentTest.start(); +} + +function buildDriverUrl() { + var driverUrl = runOptions.getDriverUrl(); + if (driverUrl != null) { + return driverUrl; + } + var s = window.location.href + var slashPairOffset = s.indexOf("//") + "//".length + var pathSlashOffset = s.substring(slashPairOffset).indexOf("/") + return s.substring(0, slashPairOffset + pathSlashOffset) + "/selenium-server/driver/"; +} + +function logToRc(logLevel, message) { + if (logLevel == null) { + logLevel = "debug"; + } + if (debugMode) { + sendToRC("logLevel=" + logLevel + ":" + message.replace(/[\n\r\015]/g, " ") + "\n", "logging=true"); + } +} + +function isArray(x) { + return ((typeof x) == "object") && (x["length"] != null); +} + +function serializeString(name, s) { + return name + "=unescape(\"" + escape(s) + "\");"; +} + +function serializeObject(name, x) +{ + var s = ''; + + if (isArray(x)) + { + s = name + "=new Array(); "; + var len = x["length"]; + for (var j = 0; j < len; j++) + { + s += serializeString(name + "[" + j + "]", x[j]); + } + } + else if (typeof x == "string") + { + s = serializeString(name, x); + } + else + { + throw "unrecognized object not encoded: " + name + "(" + x + ")"; + } + return s; +} + +function relayBotToRC(s) { +} + +// seems like no one uses this, but in fact it is called using eval from server-side PI mode code; however, +// because multiple names can map to the same popup, assigning a single name confuses matters sometimes; +// thus, I'm disabling this for now. -Nelson 10/21/06 +function setSeleniumWindowName(seleniumWindowName) { +//selenium.browserbot.getCurrentWindow()['seleniumWindowName'] = seleniumWindowName; +} + +RemoteRunner = classCreate(); +objectExtend(RemoteRunner.prototype, new TestLoop()); +objectExtend(RemoteRunner.prototype, { + initialize : function(commandFactory) { + this.commandFactory = commandFactory; + this.requiresCallBack = true; + this.commandNode = null; + this.xmlHttpForCommandsAndResults = null; + }, + + nextCommand : function() { + var urlParms = ""; + if (postResult == "START") { + urlParms += "seleniumStart=true"; + } + this.xmlHttpForCommandsAndResults = XmlHttp.create(); + sendToRC(postResult, urlParms, fnBind(this._HandleHttpResponse, this), this.xmlHttpForCommandsAndResults); + }, + + commandStarted : function(command) { + this.commandNode = document.createElement("div"); + var innerHTML = command.command + '('; + if (command.target != null && command.target != "") { + innerHTML += command.target; + if (command.value != null && command.value != "") { + innerHTML += ', ' + command.value; + } + } + innerHTML += ")"; + if (innerHTML.length >40) { + innerHTML = innerHTML.substring(0,40); + innerHTML += "..."; + } + this.commandNode.innerHTML = innerHTML; + this.commandNode.style.backgroundColor = workingColor; + if (document.getElementById("commandList") != null) { + document.getElementById("commandList").removeChild(cmd1); + document.getElementById("commandList").removeChild(cmd2); + document.getElementById("commandList").removeChild(cmd3); + document.getElementById("commandList").removeChild(cmd4); + cmd4 = cmd3; + cmd3 = cmd2; + cmd2 = cmd1; + cmd1 = this.commandNode; + document.getElementById("commandList").appendChild(cmd4); + document.getElementById("commandList").appendChild(cmd3); + document.getElementById("commandList").appendChild(cmd2); + document.getElementById("commandList").appendChild(cmd1); + } + }, + + commandComplete : function(result) { + + if (result.failed) { + if (postResult == "CONTINUATION") { + currentTest.aborted = true; + } + postResult = result.failureMessage; + this.commandNode.title = result.failureMessage; + this.commandNode.style.backgroundColor = failColor; + } else if (result.passed) { + postResult = "OK"; + this.commandNode.style.backgroundColor = passColor; + } else { + if (result.result == null) { + postResult = "OK"; + } else { + postResult = "OK," + result.result; + } + this.commandNode.style.backgroundColor = doneColor; + } + }, + + commandError : function(message) { + postResult = "ERROR: " + message; + this.commandNode.style.backgroundColor = errorColor; + this.commandNode.title = message; + }, + + testComplete : function() { + window.status = "Selenium Tests Complete, for this Test" + // Continue checking for new results + this.continueTest(); + postResult = "START"; + }, + + _HandleHttpResponse : function() { + if (this.xmlHttpForCommandsAndResults.readyState == 4) { + if (this.xmlHttpForCommandsAndResults.status == 200) { + if (this.xmlHttpForCommandsAndResults.responseText=="") { + LOG.error("saw blank string xmlHttpForCommandsAndResults.responseText"); + return; + } + var command = this._extractCommand(this.xmlHttpForCommandsAndResults); + this.currentCommand = command; + this.continueTestAtCurrentCommand(); + } else { + var s = 'xmlHttp returned: ' + this.xmlHttpForCommandsAndResults.status + ": " + this.xmlHttpForCommandsAndResults.statusText; + LOG.error(s); + this.currentCommand = null; + setTimeout(fnBind(this.continueTestAtCurrentCommand, this), 2000); + } + + } + }, + + _extractCommand : function(xmlHttp) { + var command; + try { + var re = new RegExp("^(.*?)\n((.|[\r\n])*)"); + if (re.exec(xmlHttp.responseText)) { + command = RegExp.$1; + var rest = RegExp.$2; + rest = rest.trim(); + if (rest) { + eval(rest); + } + } + else { + command = xmlHttp.responseText; + } + } catch (e) { + alert('could not get responseText: ' + e.message); + } + if (command.substr(0, '|testComplete'.length) == '|testComplete') { + return null; + } + + return this._createCommandFromRequest(command); + }, + + + _delay : function(millis) { + var startMillis = new Date(); + while (true) { + milli = new Date(); + if (milli - startMillis > millis) { + break; + } + } + }, + +// Parses a URI query string into a SeleniumCommand object + _createCommandFromRequest : function(commandRequest) { + //decodeURIComponent doesn't strip plus signs + var processed = commandRequest.replace(/\+/g, "%20"); + // strip trailing spaces + var processed = processed.replace(/\s+$/, ""); + var vars = processed.split("&"); + var cmdArgs = new Object(); + for (var i = 0; i < vars.length; i++) { + var pair = vars[i].split("="); + cmdArgs[pair[0]] = pair[1]; + } + var cmd = cmdArgs['cmd']; + var arg1 = cmdArgs['1']; + if (null == arg1) arg1 = ""; + arg1 = decodeURIComponent(arg1); + var arg2 = cmdArgs['2']; + if (null == arg2) arg2 = ""; + arg2 = decodeURIComponent(arg2); + if (cmd == null) { + throw new Error("Bad command request: " + commandRequest); + } + return new SeleniumCommand(cmd, arg1, arg2); + } + +}) + + +function sendToRC(dataToBePosted, urlParms, callback, xmlHttpObject, async) { + if (async == null) { + async = true; + } + if (xmlHttpObject == null) { + xmlHttpObject = XmlHttp.create(); + } + var url = buildDriverUrl() + "?" + if (urlParms) { + url += urlParms; + } + url += "&localFrameAddress=" + (proxyInjectionMode ? makeAddressToAUTFrame() : "top"); + url += getSeleniumWindowNameURLparameters(); + url += "&uniqueId=" + uniqueId; + + if (callback == null) { + callback = function() { + }; + } + url += buildDriverParams() + preventBrowserCaching(); + xmlHttpObject.open("POST", url, async); + xmlHttpObject.onreadystatechange = callback; + xmlHttpObject.send(dataToBePosted); + return null; +} + +function buildDriverParams() { + var params = ""; + + var sessionId = runOptions.getSessionId(); + if (sessionId == undefined) { + sessionId = injectedSessionId; + } + if (sessionId != undefined) { + params = params + "&sessionId=" + sessionId; + } + return params; +} + +function preventBrowserCaching() { + var t = (new Date()).getTime(); + return "&counterToMakeURsUniqueAndSoStopPageCachingInTheBrowser=" + t; +} + +// +// Return URL parameters pertaining to the name(s?) of the current window +// +// In selenium, the main (i.e., first) window's name is a blank string. +// +// Additional pop-ups are associated with either 1.) the name given by the 2nd parameter to window.open, or 2.) the name of a +// property on the opening window which points at the window. +// +// An example of #2: if window X contains JavaScript as follows: +// +// var windowABC = window.open(...) +// +// Note that the example JavaScript above is equivalent to +// +// window["windowABC"] = window.open(...) +// +function getSeleniumWindowNameURLparameters() { + var w = (proxyInjectionMode ? selenium.browserbot.getCurrentWindow() : window).top; + var s = "&seleniumWindowName="; + if (w.opener == null) { + return s; + } + if (w["seleniumWindowName"] == null) { + s += 'generatedSeleniumWindowName_' + Math.round(100000 * Math.random()); + } + else { + s += w["seleniumWindowName"]; + } + var windowOpener = w.opener; + for (key in windowOpener) { + var val = null; + try { + val = windowOpener[key]; + } + catch(e) { + } + if (val==w) { + s += "&jsWindowNameVar=" + key; // found a js variable in the opener referring to this window + } + } + return s; +} + +// construct a JavaScript expression which leads to my frame (i.e., the frame containing the window +// in which this code is operating) +function makeAddressToAUTFrame(w, frameNavigationalJSexpression) +{ + if (w == null) + { + w = top; + frameNavigationalJSexpression = "top"; + } + + if (w == selenium.browserbot.getCurrentWindow()) + { + return frameNavigationalJSexpression; + } + for (var j = 0; j < w.frames.length; j++) + { + var t = makeAddressToAUTFrame(w.frames[j], frameNavigationalJSexpression + ".frames[" + j + "]"); + if (t != null) + { + return t; + } + } + return null; +} |