Subversion-Projekte lars-tiefland.prado

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
/*
2
* Copyright 2005 ThoughtWorks, Inc
3
*
4
*  Licensed under the Apache License, Version 2.0 (the "License");
5
*  you may not use this file except in compliance with the License.
6
*  You may obtain a copy of the License at
7
*
8
*      http://www.apache.org/licenses/LICENSE-2.0
9
*
10
*  Unless required by applicable law or agreed to in writing, software
11
*  distributed under the License is distributed on an "AS IS" BASIS,
12
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
*  See the License for the specific language governing permissions and
14
*  limitations under the License.
15
*
16
*/
17
 
18
passColor = "#cfffcf";
19
failColor = "#ffcfcf";
20
errorColor = "#ffffff";
21
workingColor = "#DEE7EC";
22
doneColor = "#FFFFCC";
23
 
24
slowMode = false;
25
 
26
var injectedSessionId;
27
var cmd1 = document.createElement("div");
28
var cmd2 = document.createElement("div");
29
var cmd3 = document.createElement("div");
30
var cmd4 = document.createElement("div");
31
 
32
var postResult = "START";
33
var debugMode = false;
34
var relayToRC = null;
35
var proxyInjectionMode = false;
36
var uniqueId = 'sel_' + Math.round(100000 * Math.random());
37
 
38
var SeleneseRunnerOptions = Class.create();
39
Object.extend(SeleneseRunnerOptions.prototype, URLConfiguration.prototype);
40
Object.extend(SeleneseRunnerOptions.prototype, {
41
    initialize: function() {
42
        this._acquireQueryString();
43
    },
44
    getDebugMode: function() {
45
        return this._getQueryParameter("debugMode");
46
    },
47
 
48
    getContinue: function() {
49
        return this._getQueryParameter("continue");
50
    },
51
 
52
    getBaseUrl: function() {
53
        return this._getQueryParameter("baseUrl");
54
    },
55
 
56
    getDriverHost: function() {
57
        return this._getQueryParameter("driverhost");
58
    },
59
 
60
    getDriverPort: function() {
61
        return this._getQueryParameter("driverport");
62
    },
63
 
64
    getSessionId: function() {
65
        return this._getQueryParameter("sessionId");
66
    },
67
 
68
    _acquireQueryString: function () {
69
        if (this.queryString) return;
70
        if (browserVersion.isHTA) {
71
            var args = this._extractArgs();
72
            if (args.length < 2) return null;
73
            this.queryString = args[1];
74
        } else if (proxyInjectionMode) {
75
            this.queryString = selenium.browserbot.getCurrentWindow().location.search.substr(1);
76
        } else {
77
            this.queryString = top.location.search.substr(1);
78
        }
79
    }
80
 
81
});
82
var runOptions;
83
 
84
function runSeleniumTest() {
85
    runOptions = new SeleneseRunnerOptions();
86
    var testAppWindow;
87
 
88
    if (runOptions.isMultiWindowMode()) {
89
        testAppWindow = openSeparateApplicationWindow('Blank.html');
90
    } else if ($('myiframe') != null) {
91
        testAppWindow = $('myiframe').contentWindow;
92
    }
93
    else {
94
        proxyInjectionMode = true;
95
        testAppWindow = window;
96
    }
97
    selenium = Selenium.createForWindow(testAppWindow);
98
    if (!debugMode) {
99
        debugMode = runOptions.getDebugMode();
100
    }
101
    if (proxyInjectionMode) {
102
        LOG.log = logToRc;
103
        selenium.browserbot._modifyWindow(testAppWindow);
104
    }
105
    else if (debugMode) {
106
        LOG.logHook = logToRc;
107
    }
108
    window.selenium = selenium;
109
 
110
    commandFactory = new CommandHandlerFactory();
111
    commandFactory.registerAll(selenium);
112
 
113
    currentTest = new SeleneseRunner(commandFactory);
114
 
115
    if (document.getElementById("commandList") != null) {
116
        document.getElementById("commandList").appendChild(cmd4);
117
        document.getElementById("commandList").appendChild(cmd3);
118
        document.getElementById("commandList").appendChild(cmd2);
119
        document.getElementById("commandList").appendChild(cmd1);
120
    }
121
 
122
    var doContinue = runOptions.getContinue();
123
    if (doContinue != null) postResult = "OK";
124
 
125
    currentTest.start();
126
}
127
 
128
function buildBaseUrl() {
129
    var baseUrl = runOptions.getBaseUrl();
130
    if (baseUrl != null) {
131
        return baseUrl;
132
    }
133
    var s = window.location.href
134
    var slashPairOffset = s.indexOf("//") + "//".length
135
    var pathSlashOffset = s.substring(slashPairOffset).indexOf("/")
136
    return s.substring(0, slashPairOffset + pathSlashOffset) + "/selenium-server/core/";
137
}
138
 
139
function logToRc(message, logLevel) {
140
    if (logLevel == null) {
141
        logLevel = "debug";
142
    }
143
    if (debugMode) {
144
        sendToRC("logLevel=" + logLevel + ":" + message.replace(/[\n\r\015]/g, " ") + "\n");
145
    }
146
}
147
 
148
function isArray(x) {
149
    return ((typeof x) == "object") && (x["length"] != null);
150
}
151
 
152
function serializeString(name, s) {
153
    return name + "=unescape(\"" + escape(s) + "\");";
154
}
155
 
156
function serializeObject(name, x)
157
{
158
    var s = '';
159
 
160
    if (isArray(x))
161
    {
162
        s = name + "=new Array(); ";
163
        var len = x["length"];
164
        for (var j = 0; j < len; j++)
165
        {
166
            s += serializeString(name + "[" + j + "]", x[j]);
167
        }
168
    }
169
    else if (typeof x == "string")
170
    {
171
        s = serializeString(name, x);
172
    }
173
    else
174
    {
175
        throw "unrecognized object not encoded: " + name + "(" + x + ")";
176
    }
177
    return s;
178
}
179
 
180
function relayBotToRC(s) {
181
}
182
 
183
function setSeleniumWindowName(seleniumWindowName) {
184
    selenium.browserbot.getCurrentWindow()['seleniumWindowName'] = seleniumWindowName;
185
}
186
 
187
function slowClicked() {
188
    slowMode = !slowMode;
189
}
190
 
191
SeleneseRunner = Class.create();
192
Object.extend(SeleneseRunner.prototype, new TestLoop());
193
Object.extend(SeleneseRunner.prototype, {
194
    initialize : function(commandFactory) {
195
        this.commandFactory = commandFactory;
196
        this.requiresCallBack = true;
197
        this.commandNode = null;
198
        this.xmlHttpForCommandsAndResults = null;
199
    },
200
 
201
    nextCommand : function() {
202
        var urlParms = "";
203
        if (postResult == "START") {
204
            urlParms += "seleniumStart=true";
205
        }
206
        this.xmlHttpForCommandsAndResults = XmlHttp.create();
207
        sendToRC(postResult, urlParms, this._HandleHttpResponse.bind(this), this.xmlHttpForCommandsAndResults);
208
    },
209
 
210
    commandStarted : function(command) {
211
        this.commandNode = document.createElement("div");
212
        var innerHTML = command.command + '(';
213
        if (command.target != null && command.target != "") {
214
            innerHTML += command.target;
215
            if (command.value != null && command.value != "") {
216
                innerHTML += ', ' + command.value;
217
            }
218
        }
219
        innerHTML += ")";
220
        this.commandNode.innerHTML = innerHTML;
221
        this.commandNode.style.backgroundColor = workingColor;
222
        if (document.getElementById("commandList") != null) {
223
            document.getElementById("commandList").removeChild(cmd1);
224
            document.getElementById("commandList").removeChild(cmd2);
225
            document.getElementById("commandList").removeChild(cmd3);
226
            document.getElementById("commandList").removeChild(cmd4);
227
            cmd4 = cmd3;
228
            cmd3 = cmd2;
229
            cmd2 = cmd1;
230
            cmd1 = this.commandNode;
231
            document.getElementById("commandList").appendChild(cmd4);
232
            document.getElementById("commandList").appendChild(cmd3);
233
            document.getElementById("commandList").appendChild(cmd2);
234
            document.getElementById("commandList").appendChild(cmd1);
235
        }
236
    },
237
 
238
    commandComplete : function(result) {
239
 
240
        if (result.failed) {
241
            if (postResult == "CONTINUATION") {
242
                currentTest.aborted = true;
243
            }
244
            postResult = result.failureMessage;
245
            this.commandNode.title = result.failureMessage;
246
            this.commandNode.style.backgroundColor = failColor;
247
        } else if (result.passed) {
248
            postResult = "OK";
249
            this.commandNode.style.backgroundColor = passColor;
250
        } else {
251
            if (result.result == null) {
252
                postResult = "OK";
253
            } else {
254
                postResult = "OK," + result.result;
255
            }
256
            this.commandNode.style.backgroundColor = doneColor;
257
        }
258
    },
259
 
260
    commandError : function(message) {
261
        postResult = "ERROR: " + message;
262
        this.commandNode.style.backgroundColor = errorColor;
263
        this.commandNode.title = message;
264
    },
265
 
266
    testComplete : function() {
267
        window.status = "Selenium Tests Complete, for this Test"
268
        // Continue checking for new results
269
        this.continueTest();
270
        postResult = "START";
271
    },
272
 
273
    _HandleHttpResponse : function() {
274
        if (this.xmlHttpForCommandsAndResults.readyState == 4) {
275
            if (this.xmlHttpForCommandsAndResults.status == 200) {
276
                var command = this._extractCommand(this.xmlHttpForCommandsAndResults);
277
                this.currentCommand = command;
278
                this.continueTestAtCurrentCommand();
279
            } else {
280
                var s = 'xmlHttp returned: ' + this.xmlHttpForCommandsAndResults.status + ": " + this.xmlHttpForCommandsAndResults.statusText;
281
                LOG.error(s);
282
                this.currentCommand = null;
283
                setTimeout(this.continueTestAtCurrentCommand.bind(this), 2000);
284
            }
285
 
286
        }
287
    },
288
 
289
    _extractCommand : function(xmlHttp) {
290
        if (slowMode) {
291
            this._delay(2000);
292
        }
293
 
294
        var command;
295
        try {
296
            var re = new RegExp("^(.*?)\n((.|[\r\n])*)");
297
            if (re.exec(xmlHttp.responseText)) {
298
                command = RegExp.$1;
299
                var rest = RegExp.$2;
300
                rest = rest.trim();
301
                if (rest) {
302
                    eval(rest);
303
                }
304
            }
305
            else {
306
                command = xmlHttp.responseText;
307
            }
308
        } catch (e) {
309
            alert('could not get responseText: ' + e.message);
310
        }
311
        if (command.substr(0, '|testComplete'.length) == '|testComplete') {
312
            return null;
313
        }
314
 
315
        return this._createCommandFromRequest(command);
316
    },
317
 
318
 
319
    _delay : function(millis) {
320
        var startMillis = new Date();
321
        while (true) {
322
            milli = new Date();
323
            if (milli - startMillis > millis) {
324
                break;
325
            }
326
        }
327
    },
328
 
329
// Parses a URI query string into a SeleniumCommand object
330
    _createCommandFromRequest : function(commandRequest) {
331
        //decodeURIComponent doesn't strip plus signs
332
        var processed = commandRequest.replace(/\+/g, "%20");
333
        // strip trailing spaces
334
        var processed = processed.replace(/\s+$/, "");
335
        var vars = processed.split("&");
336
        var cmdArgs = new Object();
337
        for (var i = 0; i < vars.length; i++) {
338
            var pair = vars[i].split("=");
339
            cmdArgs[pair[0]] = pair[1];
340
        }
341
        var cmd = cmdArgs['cmd'];
342
        var arg1 = cmdArgs['1'];
343
        if (null == arg1) arg1 = "";
344
        arg1 = decodeURIComponent(arg1);
345
        var arg2 = cmdArgs['2'];
346
        if (null == arg2) arg2 = "";
347
        arg2 = decodeURIComponent(arg2);
348
        if (cmd == null) {
349
            throw new Error("Bad command request: " + commandRequest);
350
        }
351
        return new SeleniumCommand(cmd, arg1, arg2);
352
    }
353
 
354
})
355
 
356
 
357
function sendToRC(dataToBePosted, urlParms, callback, xmlHttpObject, async) {
358
    if (async == null) {
359
        async = true;
360
    }
361
    if (xmlHttpObject == null) {
362
        xmlHttpObject = XmlHttp.create();
363
    }
364
    var url = buildBaseUrl() + "driver/?"
365
    if (urlParms) {
366
        url += urlParms;
367
    }
368
    url += "&localFrameAddress=" + (proxyInjectionMode ? makeAddressToAUTFrame() : "top");
369
    url += "&seleniumWindowName=" + getSeleniumWindowName();
370
    url += "&uniqueId=" + uniqueId;
371
 
372
    if (callback == null) {
373
        callback = function() {
374
        };
375
    }
376
    url += buildDriverParams() + preventBrowserCaching();
377
    xmlHttpObject.open("POST", url, async);
378
    xmlHttpObject.onreadystatechange = callback;
379
    xmlHttpObject.send(dataToBePosted);
380
    return null;
381
}
382
 
383
function buildDriverParams() {
384
    var params = "";
385
 
386
    var host = runOptions.getDriverHost();
387
    var port = runOptions.getDriverPort();
388
    if (host != undefined && port != undefined) {
389
        params = params + "&driverhost=" + host + "&driverport=" + port;
390
    }
391
 
392
    var sessionId = runOptions.getSessionId();
393
    if (sessionId == undefined) {
394
        sessionId = injectedSessionId;
395
    }
396
    if (sessionId != undefined) {
397
        params = params + "&sessionId=" + sessionId;
398
    }
399
    return params;
400
}
401
 
402
function preventBrowserCaching() {
403
    var t = (new Date()).getTime();
404
    return "&counterToMakeURsUniqueAndSoStopPageCachingInTheBrowser=" + t;
405
}
406
 
407
// Return the name of the current window in the selenium recordkeeping.
408
//
409
// In selenium, the additional widow has no name.
410
//
411
// Additional pop-ups are associated with names given by the argument to the routine waitForPopUp.
412
//
413
// I try to arrange for widows which are opened in such manner to track their own names using the top-level property
414
// seleniumWindowName, but it is possible that this property will not be available (if the widow has just reloaded
415
// itself).  In this case, return "?".
416
//
417
function getSeleniumWindowName() {
418
    var w = (proxyInjectionMode ? selenium.browserbot.getCurrentWindow() : window);
419
    if (w.opener == null) {
420
        return "";
421
    }
422
    if (w["seleniumWindowName"] == null) {
423
        return "?";
424
    }
425
    return w["seleniumWindowName"];
426
}
427
 
428
// construct a JavaScript expression which leads to my frame (i.e., the frame containing the window
429
// in which this code is operating)
430
function makeAddressToAUTFrame(w, frameNavigationalJSexpression)
431
{
432
    if (w == null)
433
    {
434
        w = top;
435
        frameNavigationalJSexpression = "top";
436
    }
437
 
438
    if (w == selenium.browserbot.getCurrentWindow())
439
    {
440
        return frameNavigationalJSexpression;
441
    }
442
    for (var j = 0; j < w.frames.length; j++)
443
    {
444
        var t = makeAddressToAUTFrame(w.frames[j], frameNavigationalJSexpression + ".frames[" + j + "]");
445
        if (t != null)
446
        {
447
            return t;
448
        }
449
    }
450
    return null;
451
}