selenium-core-runner 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. data/Gemfile +9 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +3 -0
  4. data/Rakefile +30 -0
  5. data/app/controllers/selenium_core_runner/suites_controller.rb +19 -0
  6. data/app/views/selenium_core_runner/suites/index.html.erb +177 -0
  7. data/app/views/selenium_core_runner/suites/show.html.erb +0 -0
  8. data/config/routes.rb +6 -0
  9. data/lib/selenium-core-runner/engine.rb +19 -0
  10. data/lib/selenium-core-runner.rb +3 -0
  11. data/public/selenium-core-runner/Blank.html +7 -0
  12. data/public/selenium-core-runner/InjectedRemoteRunner.html +8 -0
  13. data/public/selenium-core-runner/RemoteRunner.html +101 -0
  14. data/public/selenium-core-runner/SeleniumLog.html +109 -0
  15. data/public/selenium-core-runner/TestPrompt.html +145 -0
  16. data/public/selenium-core-runner/TestRunner-splash.html +55 -0
  17. data/public/selenium-core-runner/TestRunner.hta +177 -0
  18. data/public/selenium-core-runner/TestRunner.html +177 -0
  19. data/public/selenium-core-runner/icons/all.png +0 -0
  20. data/public/selenium-core-runner/icons/continue.png +0 -0
  21. data/public/selenium-core-runner/icons/continue_disabled.png +0 -0
  22. data/public/selenium-core-runner/icons/pause.png +0 -0
  23. data/public/selenium-core-runner/icons/pause_disabled.png +0 -0
  24. data/public/selenium-core-runner/icons/selected.png +0 -0
  25. data/public/selenium-core-runner/icons/step.png +0 -0
  26. data/public/selenium-core-runner/icons/step_disabled.png +0 -0
  27. data/public/selenium-core-runner/iedoc-core.xml +1789 -0
  28. data/public/selenium-core-runner/iedoc.xml +1830 -0
  29. data/public/selenium-core-runner/lib/cssQuery/cssQuery-p.js +6 -0
  30. data/public/selenium-core-runner/lib/cssQuery/src/cssQuery-level2.js +142 -0
  31. data/public/selenium-core-runner/lib/cssQuery/src/cssQuery-level3.js +150 -0
  32. data/public/selenium-core-runner/lib/cssQuery/src/cssQuery-standard.js +53 -0
  33. data/public/selenium-core-runner/lib/cssQuery/src/cssQuery.js +356 -0
  34. data/public/selenium-core-runner/lib/prototype.js +2006 -0
  35. data/public/selenium-core-runner/lib/scriptaculous/builder.js +101 -0
  36. data/public/selenium-core-runner/lib/scriptaculous/controls.js +815 -0
  37. data/public/selenium-core-runner/lib/scriptaculous/dragdrop.js +915 -0
  38. data/public/selenium-core-runner/lib/scriptaculous/effects.js +958 -0
  39. data/public/selenium-core-runner/lib/scriptaculous/scriptaculous.js +47 -0
  40. data/public/selenium-core-runner/lib/scriptaculous/slider.js +283 -0
  41. data/public/selenium-core-runner/lib/scriptaculous/unittest.js +383 -0
  42. data/public/selenium-core-runner/lib/snapsie.js +91 -0
  43. data/public/selenium-core-runner/scripts/find_matching_child.js +69 -0
  44. data/public/selenium-core-runner/scripts/htmlutils.js +1623 -0
  45. data/public/selenium-core-runner/scripts/injection.html +72 -0
  46. data/public/selenium-core-runner/scripts/selenium-api.js +3240 -0
  47. data/public/selenium-core-runner/scripts/selenium-browserbot.js +2333 -0
  48. data/public/selenium-core-runner/scripts/selenium-browserdetect.js +153 -0
  49. data/public/selenium-core-runner/scripts/selenium-commandhandlers.js +379 -0
  50. data/public/selenium-core-runner/scripts/selenium-executionloop.js +175 -0
  51. data/public/selenium-core-runner/scripts/selenium-logging.js +148 -0
  52. data/public/selenium-core-runner/scripts/selenium-remoterunner.js +695 -0
  53. data/public/selenium-core-runner/scripts/selenium-testrunner.js +1362 -0
  54. data/public/selenium-core-runner/scripts/selenium-version.js +5 -0
  55. data/public/selenium-core-runner/scripts/ui-doc.html +803 -0
  56. data/public/selenium-core-runner/scripts/ui-element.js +1627 -0
  57. data/public/selenium-core-runner/scripts/ui-map-sample.js +979 -0
  58. data/public/selenium-core-runner/scripts/user-extensions.js +3 -0
  59. data/public/selenium-core-runner/scripts/user-extensions.js.sample +75 -0
  60. data/public/selenium-core-runner/scripts/xmlextras.js +153 -0
  61. data/public/selenium-core-runner/selenium-logo.png +0 -0
  62. data/public/selenium-core-runner/selenium-test.css +43 -0
  63. data/public/selenium-core-runner/selenium.css +316 -0
  64. data/public/selenium-core-runner/xpath/dom.js +566 -0
  65. data/public/selenium-core-runner/xpath/javascript-xpath-0.1.11.js +2816 -0
  66. data/public/selenium-core-runner/xpath/util.js +549 -0
  67. data/public/selenium-core-runner/xpath/xmltoken.js +149 -0
  68. data/public/selenium-core-runner/xpath/xpath.js +2481 -0
  69. metadata +121 -0
@@ -0,0 +1,153 @@
1
+ /*
2
+ * Copyright 2004 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
+ // Although it's generally better web development practice not to use
19
+ // browser-detection (feature detection is better), the subtle browser
20
+ // differences that Selenium has to work around seem to make it
21
+ // necessary. Maybe as we learn more about what we need, we can do this in
22
+ // a more "feature-centric" rather than "browser-centric" way.
23
+
24
+ var BrowserVersion = function() {
25
+ this.name = navigator.appName;
26
+
27
+ if (navigator.userAgent.indexOf('Mac OS X') != -1) {
28
+ this.isOSX = true;
29
+ }
30
+
31
+ if (navigator.userAgent.indexOf('Windows NT 6') != -1) {
32
+ this.isVista = true;
33
+ }
34
+
35
+ if (window.opera != null) {
36
+ this.browser = BrowserVersion.OPERA;
37
+ this.isOpera = true;
38
+ return;
39
+ }
40
+
41
+ var _getQueryParameter = function(searchKey) {
42
+ var str = location.search.substr(1);
43
+ if (str == null) return null;
44
+ var clauses = str.split('&');
45
+ for (var i = 0; i < clauses.length; i++) {
46
+ var keyValuePair = clauses[i].split('=', 2);
47
+ var key = unescape(keyValuePair[0]);
48
+ if (key == searchKey) {
49
+ return unescape(keyValuePair[1]);
50
+ }
51
+ }
52
+ return null;
53
+ };
54
+
55
+ var self = this;
56
+
57
+ var checkChrome = function() {
58
+ var loc = window.document.location.href;
59
+ try {
60
+ loc = window.top.document.location.href;
61
+ if (/^chrome:\/\//.test(loc)) {
62
+ self.isChrome = true;
63
+ } else {
64
+ self.isChrome = false;
65
+ }
66
+ } catch (e) {
67
+ // can't see the top (that means we might be chrome, but it's impossible to be sure)
68
+ self.isChromeDetectable = "no, top location couldn't be read in this window";
69
+ if (_getQueryParameter('thisIsChrome')) {
70
+ self.isChrome = true;
71
+ } else {
72
+ self.isChrome = false;
73
+ }
74
+ }
75
+
76
+
77
+ }
78
+
79
+
80
+
81
+ if (this.name == "Microsoft Internet Explorer") {
82
+ this.browser = BrowserVersion.IE;
83
+ this.isIE = true;
84
+ try {
85
+ if (window.top.SeleniumHTARunner && window.top.document.location.pathname.match(/.hta$/i)) {
86
+ this.isHTA = true;
87
+ }
88
+ } catch (e) {
89
+ this.isHTADetectable = "no, top location couldn't be read in this window";
90
+ if (_getQueryParameter('thisIsHTA')) {
91
+ self.isHTA = true;
92
+ } else {
93
+ self.isHTA = false;
94
+ }
95
+ }
96
+ if (navigator.appVersion.match(/MSIE 6.0/)) {
97
+ this.isIE6 = true;
98
+ }
99
+ if ("0" == navigator.appMinorVersion) {
100
+ this.preSV1 = true;
101
+ if (this.isIE6) {
102
+ this.appearsToBeBrokenInitialIE6 = true;
103
+ }
104
+ }
105
+ return;
106
+ }
107
+
108
+ if (navigator.userAgent.indexOf('Safari') != -1) {
109
+ this.browser = BrowserVersion.SAFARI;
110
+ this.isSafari = true;
111
+ this.khtml = true;
112
+ return;
113
+ }
114
+
115
+ if (navigator.userAgent.indexOf('Konqueror') != -1) {
116
+ this.browser = BrowserVersion.KONQUEROR;
117
+ this.isKonqueror = true;
118
+ this.khtml = true;
119
+ return;
120
+ }
121
+
122
+ if (navigator.userAgent.indexOf('Firefox') != -1) {
123
+ this.browser = BrowserVersion.FIREFOX;
124
+ this.isFirefox = true;
125
+ this.isGecko = true;
126
+ var result = /.*Firefox\/([\d\.]+).*/.exec(navigator.userAgent);
127
+ if (result) {
128
+ this.firefoxVersion = result[1];
129
+ }
130
+ checkChrome();
131
+ return;
132
+ }
133
+
134
+ if (navigator.userAgent.indexOf('Gecko') != -1) {
135
+ this.browser = BrowserVersion.MOZILLA;
136
+ this.isMozilla = true;
137
+ this.isGecko = true;
138
+ checkChrome();
139
+ return;
140
+ }
141
+
142
+ this.browser = BrowserVersion.UNKNOWN;
143
+ }
144
+
145
+ BrowserVersion.OPERA = "Opera";
146
+ BrowserVersion.IE = "IE";
147
+ BrowserVersion.KONQUEROR = "Konqueror";
148
+ BrowserVersion.SAFARI = "Safari";
149
+ BrowserVersion.FIREFOX = "Firefox";
150
+ BrowserVersion.MOZILLA = "Mozilla";
151
+ BrowserVersion.UNKNOWN = "Unknown";
152
+
153
+ var browserVersion = new BrowserVersion();
@@ -0,0 +1,379 @@
1
+ /*
2
+ * Copyright 2004 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
+ // A naming convention used in this file:
18
+ //
19
+ //
20
+ // - a "seleniumApi" is an instance of the Selenium object, defined in selenium-api.js.
21
+ //
22
+ // - a "Method" is an unbound function whose target must be supplied when it's called, ie.
23
+ // it should be invoked using Function.call() or Function.apply()
24
+ //
25
+ // - a "Block" is a function that has been bound to a target object, so can be called invoked directly
26
+ // (or with a null target)
27
+ //
28
+ // - "CommandHandler" is effectively an abstract base for
29
+ // various handlers including ActionHandler, AccessorHandler and AssertHandler.
30
+ // Subclasses need to implement an execute(seleniumApi, command) function,
31
+ // where seleniumApi is the Selenium object, and command a SeleniumCommand object.
32
+ //
33
+ // - Handlers will return a "result" object (ActionResult, AccessorResult, AssertResult).
34
+ // ActionResults may contain a .terminationCondition function which is run by
35
+ // -executionloop.js after the command is run; we'll run it over and over again
36
+ // until it returns true or the .terminationCondition throws an exception.
37
+ // AccessorResults will contain the results of running getter (e.g. getTitle returns
38
+ // the title as a string).
39
+
40
+ var CommandHandlerFactory = classCreate();
41
+ objectExtend(CommandHandlerFactory.prototype, {
42
+
43
+ initialize: function() {
44
+ this.handlers = {};
45
+ },
46
+
47
+ registerAction: function(name, actionBlock, wait, dontCheckAlertsAndConfirms) {
48
+ this.handlers[name] = new ActionHandler(actionBlock, wait, dontCheckAlertsAndConfirms);
49
+ },
50
+
51
+ registerAccessor: function(name, accessBlock) {
52
+ this.handlers[name] = new AccessorHandler(accessBlock);
53
+ },
54
+
55
+ registerAssert: function(name, assertBlock, haltOnFailure) {
56
+ this.handlers[name] = new AssertHandler(assertBlock, haltOnFailure);
57
+ },
58
+
59
+ getCommandHandler: function(name) {
60
+ return this.handlers[name];
61
+ },
62
+
63
+ _registerAllAccessors: function(seleniumApi) {
64
+ // Methods of the form getFoo(target) result in commands:
65
+ // getFoo, assertFoo, verifyFoo, assertNotFoo, verifyNotFoo
66
+ // storeFoo, waitForFoo, and waitForNotFoo.
67
+ for (var functionName in seleniumApi) {
68
+ var match = /^(get|is)([A-Z].+)$/.exec(functionName);
69
+ if (match) {
70
+ var accessMethod = seleniumApi[functionName];
71
+ var accessBlock = fnBind(accessMethod, seleniumApi);
72
+ var baseName = match[2];
73
+ var isBoolean = (match[1] == "is");
74
+ var requiresTarget = (accessMethod.length == 1);
75
+
76
+ this.registerAccessor(functionName, accessBlock);
77
+ this._registerStoreCommandForAccessor(baseName, accessBlock, requiresTarget);
78
+
79
+ var predicateBlock = this._predicateForAccessor(accessBlock, requiresTarget, isBoolean);
80
+ this._registerAssertionsForPredicate(baseName, predicateBlock);
81
+ this._registerWaitForCommandsForPredicate(seleniumApi, baseName, predicateBlock);
82
+ }
83
+ }
84
+ },
85
+
86
+ _registerAllActions: function(seleniumApi) {
87
+ for (var functionName in seleniumApi) {
88
+ var match = /^do([A-Z].+)$/.exec(functionName);
89
+ if (match) {
90
+ var actionName = match[1].lcfirst();
91
+ var actionMethod = seleniumApi[functionName];
92
+ var dontCheckPopups = actionMethod.dontCheckAlertsAndConfirms;
93
+ var actionBlock = fnBind(actionMethod, seleniumApi);
94
+ this.registerAction(actionName, actionBlock, false, dontCheckPopups);
95
+ this.registerAction(actionName + "AndWait", actionBlock, true, dontCheckPopups);
96
+ }
97
+ }
98
+ },
99
+
100
+ _registerAllAsserts: function(seleniumApi) {
101
+ for (var functionName in seleniumApi) {
102
+ var match = /^assert([A-Z].+)$/.exec(functionName);
103
+ if (match) {
104
+ var assertBlock = fnBind(seleniumApi[functionName], seleniumApi);
105
+
106
+ // Register the assert with the "assert" prefix, and halt on failure.
107
+ var assertName = functionName;
108
+ this.registerAssert(assertName, assertBlock, true);
109
+
110
+ // Register the assert with the "verify" prefix, and do not halt on failure.
111
+ var verifyName = "verify" + match[1];
112
+ this.registerAssert(verifyName, assertBlock, false);
113
+ }
114
+ }
115
+ },
116
+
117
+ registerAll: function(seleniumApi) {
118
+ this._registerAllAccessors(seleniumApi);
119
+ this._registerAllActions(seleniumApi);
120
+ this._registerAllAsserts(seleniumApi);
121
+ },
122
+
123
+ _predicateForAccessor: function(accessBlock, requiresTarget, isBoolean) {
124
+ if (isBoolean) {
125
+ return this._predicateForBooleanAccessor(accessBlock);
126
+ }
127
+ if (requiresTarget) {
128
+ return this._predicateForSingleArgAccessor(accessBlock);
129
+ }
130
+ return this._predicateForNoArgAccessor(accessBlock);
131
+ },
132
+
133
+ _predicateForSingleArgAccessor: function(accessBlock) {
134
+ // Given an accessor function getBlah(target),
135
+ // return a "predicate" equivalient to isBlah(target, value) that
136
+ // is true when the value returned by the accessor matches the specified value.
137
+ return function(target, value) {
138
+ var accessorResult = accessBlock(target);
139
+ accessorResult = selArrayToString(accessorResult);
140
+ if (PatternMatcher.matches(value, accessorResult)) {
141
+ return new PredicateResult(true, "Actual value '" + accessorResult + "' did match '" + value + "'");
142
+ } else {
143
+ return new PredicateResult(false, "Actual value '" + accessorResult + "' did not match '" + value + "'");
144
+ }
145
+ };
146
+ },
147
+
148
+ _predicateForNoArgAccessor: function(accessBlock) {
149
+ // Given a (no-arg) accessor function getBlah(),
150
+ // return a "predicate" equivalient to isBlah(value) that
151
+ // is true when the value returned by the accessor matches the specified value.
152
+ return function(value) {
153
+ var accessorResult = accessBlock();
154
+ accessorResult = selArrayToString(accessorResult);
155
+ if (PatternMatcher.matches(value, accessorResult)) {
156
+ return new PredicateResult(true, "Actual value '" + accessorResult + "' did match '" + value + "'");
157
+ } else {
158
+ return new PredicateResult(false, "Actual value '" + accessorResult + "' did not match '" + value + "'");
159
+ }
160
+ };
161
+ },
162
+
163
+ _predicateForBooleanAccessor: function(accessBlock) {
164
+ // Given a boolean accessor function isBlah(),
165
+ // return a "predicate" equivalient to isBlah() that
166
+ // returns an appropriate PredicateResult value.
167
+ return function() {
168
+ var accessorResult;
169
+ if (arguments.length > 2) throw new SeleniumError("Too many arguments! " + arguments.length);
170
+ if (arguments.length == 2) {
171
+ accessorResult = accessBlock(arguments[0], arguments[1]);
172
+ } else if (arguments.length == 1) {
173
+ accessorResult = accessBlock(arguments[0]);
174
+ } else {
175
+ accessorResult = accessBlock();
176
+ }
177
+ if (accessorResult) {
178
+ return new PredicateResult(true, "true");
179
+ } else {
180
+ return new PredicateResult(false, "false");
181
+ }
182
+ };
183
+ },
184
+
185
+ _invertPredicate: function(predicateBlock) {
186
+ // Given a predicate, return the negation of that predicate.
187
+ // Leaves the message unchanged.
188
+ // Used to create assertNot, verifyNot, and waitForNot commands.
189
+ return function(target, value) {
190
+ var result = predicateBlock(target, value);
191
+ result.isTrue = !result.isTrue;
192
+ return result;
193
+ };
194
+ },
195
+
196
+ createAssertionFromPredicate: function(predicateBlock) {
197
+ // Convert an isBlahBlah(target, value) function into an assertBlahBlah(target, value) function.
198
+ return function(target, value) {
199
+ var result = predicateBlock(target, value);
200
+ if (!result.isTrue) {
201
+ Assert.fail(result.message);
202
+ }
203
+ };
204
+ },
205
+
206
+ _invertPredicateName: function(baseName) {
207
+ var matchResult = /^(.*)Present$/.exec(baseName);
208
+ if (matchResult != null) {
209
+ return matchResult[1] + "NotPresent";
210
+ }
211
+ return "Not" + baseName;
212
+ },
213
+
214
+ _registerAssertionsForPredicate: function(baseName, predicateBlock) {
215
+ // Register an assertion, a verification, a negative assertion,
216
+ // and a negative verification based on the specified accessor.
217
+ var assertBlock = this.createAssertionFromPredicate(predicateBlock);
218
+ this.registerAssert("assert" + baseName, assertBlock, true);
219
+ this.registerAssert("verify" + baseName, assertBlock, false);
220
+
221
+ var invertedPredicateBlock = this._invertPredicate(predicateBlock);
222
+ var negativeassertBlock = this.createAssertionFromPredicate(invertedPredicateBlock);
223
+ this.registerAssert("assert" + this._invertPredicateName(baseName), negativeassertBlock, true);
224
+ this.registerAssert("verify" + this._invertPredicateName(baseName), negativeassertBlock, false);
225
+ },
226
+
227
+ _waitForActionForPredicate: function(predicateBlock) {
228
+ // Convert an isBlahBlah(target, value) function into a waitForBlahBlah(target, value) function.
229
+ return function(target, value) {
230
+ var terminationCondition = function () {
231
+ try {
232
+ return predicateBlock(target, value).isTrue;
233
+ } catch (e) {
234
+ // Treat exceptions as meaning the condition is not yet met.
235
+ // Useful, for example, for waitForValue when the element has
236
+ // not even been created yet.
237
+ // TODO: possibly should rethrow some types of exception.
238
+ return false;
239
+ }
240
+ };
241
+ return Selenium.decorateFunctionWithTimeout(terminationCondition, this.defaultTimeout);
242
+ };
243
+ },
244
+
245
+ _registerWaitForCommandsForPredicate: function(seleniumApi, baseName, predicateBlock) {
246
+ // Register a waitForBlahBlah and waitForNotBlahBlah based on the specified accessor.
247
+ var waitForActionMethod = this._waitForActionForPredicate(predicateBlock);
248
+ var waitForActionBlock = fnBind(waitForActionMethod, seleniumApi);
249
+
250
+ var invertedPredicateBlock = this._invertPredicate(predicateBlock);
251
+ var waitForNotActionMethod = this._waitForActionForPredicate(invertedPredicateBlock);
252
+ var waitForNotActionBlock = fnBind(waitForNotActionMethod, seleniumApi);
253
+
254
+ this.registerAction("waitFor" + baseName, waitForActionBlock, false, true);
255
+ this.registerAction("waitFor" + this._invertPredicateName(baseName), waitForNotActionBlock, false, true);
256
+ //TODO decide remove "waitForNot.*Present" action name or not
257
+ //for the back compatiblity issues we still make waitForNot.*Present availble
258
+ this.registerAction("waitForNot" + baseName, waitForNotActionBlock, false, true);
259
+ },
260
+
261
+ _registerStoreCommandForAccessor: function(baseName, accessBlock, requiresTarget) {
262
+ var action;
263
+ if (requiresTarget) {
264
+ action = function(target, varName) {
265
+ storedVars[varName] = accessBlock(target);
266
+ };
267
+ } else {
268
+ action = function(varName) {
269
+ storedVars[varName] = accessBlock();
270
+ };
271
+ }
272
+ this.registerAction("store" + baseName, action, false, true);
273
+ }
274
+
275
+ });
276
+
277
+ function PredicateResult(isTrue, message) {
278
+ this.isTrue = isTrue;
279
+ this.message = message;
280
+ }
281
+
282
+ // NOTE: The CommandHandler is effectively an abstract base for
283
+ // various handlers including ActionHandler, AccessorHandler and AssertHandler.
284
+ // Subclasses need to implement an execute(seleniumApi, command) function,
285
+ // where seleniumApi is the Selenium object, and command a SeleniumCommand object.
286
+ function CommandHandler(type, haltOnFailure) {
287
+ this.type = type;
288
+ this.haltOnFailure = haltOnFailure;
289
+ }
290
+
291
+ // An ActionHandler is a command handler that executes the sepcified action,
292
+ // possibly checking for alerts and confirmations (if checkAlerts is set), and
293
+ // possibly waiting for a page load if wait is set.
294
+ function ActionHandler(actionBlock, wait, dontCheckAlerts) {
295
+ this.actionBlock = actionBlock;
296
+ CommandHandler.call(this, "action", true);
297
+ if (wait) {
298
+ this.wait = true;
299
+ }
300
+ // note that dontCheckAlerts could be undefined!!!
301
+ this.checkAlerts = (dontCheckAlerts) ? false : true;
302
+ }
303
+ ActionHandler.prototype = new CommandHandler;
304
+ ActionHandler.prototype.execute = function(seleniumApi, command) {
305
+ if (this.checkAlerts && (null == /(Alert|Confirmation)(Not)?Present/.exec(command.command))) {
306
+ // todo: this conditional logic is ugly
307
+ seleniumApi.ensureNoUnhandledPopups();
308
+ }
309
+
310
+ var handlerCondition = this.actionBlock(command.target, command.value);
311
+
312
+ // page load waiting takes precedence over any wait condition returned by
313
+ // the action handler.
314
+ var terminationCondition = (this.wait)
315
+ ? seleniumApi.makePageLoadCondition() : handlerCondition;
316
+
317
+ return new ActionResult(terminationCondition);
318
+ };
319
+
320
+ function ActionResult(terminationCondition) {
321
+ this.terminationCondition = terminationCondition;
322
+ }
323
+
324
+ function AccessorHandler(accessBlock) {
325
+ this.accessBlock = accessBlock;
326
+ CommandHandler.call(this, "accessor", true);
327
+ }
328
+ AccessorHandler.prototype = new CommandHandler;
329
+ AccessorHandler.prototype.execute = function(seleniumApi, command) {
330
+ var returnValue = this.accessBlock(command.target, command.value);
331
+ return new AccessorResult(returnValue);
332
+ };
333
+
334
+ function AccessorResult(result) {
335
+ this.result = result;
336
+ }
337
+
338
+ /**
339
+ * Handler for assertions and verifications.
340
+ */
341
+ function AssertHandler(assertBlock, haltOnFailure) {
342
+ this.assertBlock = assertBlock;
343
+ CommandHandler.call(this, "assert", haltOnFailure || false);
344
+ }
345
+ AssertHandler.prototype = new CommandHandler;
346
+ AssertHandler.prototype.execute = function(seleniumApi, command) {
347
+ var result = new AssertResult();
348
+ try {
349
+ this.assertBlock(command.target, command.value);
350
+ } catch (e) {
351
+ // If this is not a AssertionFailedError, or we should haltOnFailure, rethrow.
352
+ if (!e.isAssertionFailedError) {
353
+ throw e;
354
+ }
355
+ if (this.haltOnFailure) {
356
+ var error = new SeleniumError(e.failureMessage);
357
+ throw error;
358
+ }
359
+ result.setFailed(e.failureMessage);
360
+ }
361
+ return result;
362
+ };
363
+
364
+ function AssertResult() {
365
+ this.passed = true;
366
+ }
367
+ AssertResult.prototype.setFailed = function(message) {
368
+ this.passed = null;
369
+ this.failed = true;
370
+ this.failureMessage = message;
371
+ }
372
+
373
+ function SeleniumCommand(command, target, value, isBreakpoint) {
374
+ this.command = command;
375
+ this.target = target;
376
+ this.value = value;
377
+ this.isBreakpoint = isBreakpoint;
378
+ }
379
+