rubinium 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (161) hide show
  1. data/CHANGES +7 -0
  2. data/MIT-LICENSE +21 -0
  3. data/README +137 -0
  4. data/Rakefile +139 -0
  5. data/TODO +7 -0
  6. data/doc/examples/rtc_site_live.rb +12 -0
  7. data/doc/examples/rts_main.rb +9 -0
  8. data/doc/examples/rts_shared_code.rb +25 -0
  9. data/lib/rubinium.rb +9 -0
  10. data/lib/rubinium/string.rb +3 -0
  11. data/lib/rubinium/test_base.rb +80 -0
  12. data/lib/rubinium/test_suite.rb +53 -0
  13. data/lib/rubinium/validator.rb +16 -0
  14. data/test/selenium_tests/test_click.rb +22 -0
  15. data/test/selenium_tests/test_open.rb +11 -0
  16. data/test/tc_file_creation.rb +60 -0
  17. data/test/ts_rubinium.rb +1 -0
  18. data/vendor/selenium-0.6.0/install-readme.txt +9 -0
  19. data/vendor/selenium-0.6.0/selenium/SeleneseRunner.html +253 -0
  20. data/vendor/selenium-0.6.0/selenium/SeleniumLog.html +61 -0
  21. data/vendor/selenium-0.6.0/selenium/TestRunner-splash.html +55 -0
  22. data/vendor/selenium-0.6.0/selenium/TestRunner.hta +146 -0
  23. data/vendor/selenium-0.6.0/selenium/TestRunner.html +146 -0
  24. data/vendor/selenium-0.6.0/selenium/devtests/TestClickInFrame.html +58 -0
  25. data/vendor/selenium-0.6.0/selenium/devtests/TestOpenInFrame.html +48 -0
  26. data/vendor/selenium-0.6.0/selenium/devtests/TestOpenInNewWindow.html +78 -0
  27. data/vendor/selenium-0.6.0/selenium/devtests/TestOpenMeta.html +43 -0
  28. data/vendor/selenium-0.6.0/selenium/devtests/TestSuite.html +39 -0
  29. data/vendor/selenium-0.6.0/selenium/devtests/meta/page.html +5 -0
  30. data/vendor/selenium-0.6.0/selenium/dom-images/butmin.gif +0 -0
  31. data/vendor/selenium-0.6.0/selenium/dom-images/butplus.gif +0 -0
  32. data/vendor/selenium-0.6.0/selenium/dom-styles/default.css +298 -0
  33. data/vendor/selenium-0.6.0/selenium/domviewer.html +16 -0
  34. data/vendor/selenium-0.6.0/selenium/html-xpath/carnation.jpg +0 -0
  35. data/vendor/selenium-0.6.0/selenium/html-xpath/example.html +75 -0
  36. data/vendor/selenium-0.6.0/selenium/html-xpath/html-xpath-patched.js +657 -0
  37. data/vendor/selenium-0.6.0/selenium/html-xpath/html-xpath.js +610 -0
  38. data/vendor/selenium-0.6.0/selenium/html-xpath/license.txt +504 -0
  39. data/vendor/selenium-0.6.0/selenium/html-xpath/rainbow.jpg +0 -0
  40. data/vendor/selenium-0.6.0/selenium/htmlutils.js +283 -0
  41. data/vendor/selenium-0.6.0/selenium/index.html +60 -0
  42. data/vendor/selenium-0.6.0/selenium/jsmock/mock-tests.html +205 -0
  43. data/vendor/selenium-0.6.0/selenium/jsmock/mock.js +124 -0
  44. data/vendor/selenium-0.6.0/selenium/selenium-api.js +683 -0
  45. data/vendor/selenium-0.6.0/selenium/selenium-browserbot.js +930 -0
  46. data/vendor/selenium-0.6.0/selenium/selenium-commandhandlers.js +286 -0
  47. data/vendor/selenium-0.6.0/selenium/selenium-domviewer.js +188 -0
  48. data/vendor/selenium-0.6.0/selenium/selenium-executionloop.js +250 -0
  49. data/vendor/selenium-0.6.0/selenium/selenium-fitrunner.js +597 -0
  50. data/vendor/selenium-0.6.0/selenium/selenium-logging.js +88 -0
  51. data/vendor/selenium-0.6.0/selenium/selenium-logo.png +0 -0
  52. data/vendor/selenium-0.6.0/selenium/selenium-tableparser.js +50 -0
  53. data/vendor/selenium-0.6.0/selenium/selenium.css +211 -0
  54. data/vendor/selenium-0.6.0/selenium/tests/ErrorCheckingTestSuite.html +36 -0
  55. data/vendor/selenium-0.6.0/selenium/tests/GoogleTestSearch.html +69 -0
  56. data/vendor/selenium-0.6.0/selenium/tests/GoogleTestSuite.html +32 -0
  57. data/vendor/selenium-0.6.0/selenium/tests/JsUnitSuite.html +38 -0
  58. data/vendor/selenium-0.6.0/selenium/tests/TestClick.html +128 -0
  59. data/vendor/selenium-0.6.0/selenium/tests/TestClickJavascriptHref.html +115 -0
  60. data/vendor/selenium-0.6.0/selenium/tests/TestCommandError.html +79 -0
  61. data/vendor/selenium-0.6.0/selenium/tests/TestConfirmations.html +77 -0
  62. data/vendor/selenium-0.6.0/selenium/tests/TestErrorChecking.html +71 -0
  63. data/vendor/selenium-0.6.0/selenium/tests/TestFailingAssert.html +59 -0
  64. data/vendor/selenium-0.6.0/selenium/tests/TestFailingVerifications.html +198 -0
  65. data/vendor/selenium-0.6.0/selenium/tests/TestFocusOnBlur.html +53 -0
  66. data/vendor/selenium-0.6.0/selenium/tests/TestGoBack.html +81 -0
  67. data/vendor/selenium-0.6.0/selenium/tests/TestImplicitLocators.html +81 -0
  68. data/vendor/selenium-0.6.0/selenium/tests/TestJavascriptParameters.html +91 -0
  69. data/vendor/selenium-0.6.0/selenium/tests/TestLocators.html +161 -0
  70. data/vendor/selenium-0.6.0/selenium/tests/TestModalDialog.html +58 -0
  71. data/vendor/selenium-0.6.0/selenium/tests/TestModalDialogDialog.html +48 -0
  72. data/vendor/selenium-0.6.0/selenium/tests/TestOpen.html +66 -0
  73. data/vendor/selenium-0.6.0/selenium/tests/TestPatternMatching.html +127 -0
  74. data/vendor/selenium-0.6.0/selenium/tests/TestPause.html +78 -0
  75. data/vendor/selenium-0.6.0/selenium/tests/TestPrompting.html +82 -0
  76. data/vendor/selenium-0.6.0/selenium/tests/TestProxy.html +62 -0
  77. data/vendor/selenium-0.6.0/selenium/tests/TestSelect.html +111 -0
  78. data/vendor/selenium-0.6.0/selenium/tests/TestSelectWindow.html +106 -0
  79. data/vendor/selenium-0.6.0/selenium/tests/TestStore.html +165 -0
  80. data/vendor/selenium-0.6.0/selenium/tests/TestSuite-InternetExplorer.html +79 -0
  81. data/vendor/selenium-0.6.0/selenium/tests/TestSuite-Konqueror.html +75 -0
  82. data/vendor/selenium-0.6.0/selenium/tests/TestSuite-Safari.html +75 -0
  83. data/vendor/selenium-0.6.0/selenium/tests/TestSuite.html +75 -0
  84. data/vendor/selenium-0.6.0/selenium/tests/TestType.html +79 -0
  85. data/vendor/selenium-0.6.0/selenium/tests/TestUserExtensions.html +81 -0
  86. data/vendor/selenium-0.6.0/selenium/tests/TestVerifications.html +164 -0
  87. data/vendor/selenium-0.6.0/selenium/tests/TestVerifyAlerts.html +80 -0
  88. data/vendor/selenium-0.6.0/selenium/tests/TestVerifyAlertsFailures.html +108 -0
  89. data/vendor/selenium-0.6.0/selenium/tests/TestVerifyConfirmationFailures.html +86 -0
  90. data/vendor/selenium-0.6.0/selenium/tests/TestVerifyEditable.html +70 -0
  91. data/vendor/selenium-0.6.0/selenium/tests/TestVerifyEditableFailures.html +95 -0
  92. data/vendor/selenium-0.6.0/selenium/tests/TestVisibility.html +91 -0
  93. data/vendor/selenium-0.6.0/selenium/tests/TestVisibilityFailures.html +131 -0
  94. data/vendor/selenium-0.6.0/selenium/tests/TestWait.html +112 -0
  95. data/vendor/selenium-0.6.0/selenium/tests/TestWaitFor.html +63 -0
  96. data/vendor/selenium-0.6.0/selenium/tests/TestWaitInPopupWindow.html +94 -0
  97. data/vendor/selenium-0.6.0/selenium/tests/TestXPathLocators.html +98 -0
  98. data/vendor/selenium-0.6.0/selenium/tests/browserbot/alert-handling-tests.html +79 -0
  99. data/vendor/selenium-0.6.0/selenium/tests/browserbot/assert-tests.html +113 -0
  100. data/vendor/selenium-0.6.0/selenium/tests/browserbot/browserbot-tests.html +123 -0
  101. data/vendor/selenium-0.6.0/selenium/tests/browserbot/command-factory-tests.html +290 -0
  102. data/vendor/selenium-0.6.0/selenium/tests/browserbot/command-handler-tests.html +115 -0
  103. data/vendor/selenium-0.6.0/selenium/tests/browserbot/confirm-handling-tests.html +97 -0
  104. data/vendor/selenium-0.6.0/selenium/tests/browserbot/error-checking-command-tests.html +198 -0
  105. data/vendor/selenium-0.6.0/selenium/tests/browserbot/event-bubble-tests.html +106 -0
  106. data/vendor/selenium-0.6.0/selenium/tests/browserbot/optionlocator-tests.html +180 -0
  107. data/vendor/selenium-0.6.0/selenium/tests/browserbot/pagebot-accessor-tests.html +65 -0
  108. data/vendor/selenium-0.6.0/selenium/tests/browserbot/pagebot-action-tests.html +200 -0
  109. data/vendor/selenium-0.6.0/selenium/tests/browserbot/pagebot-attribute-tests.html +98 -0
  110. data/vendor/selenium-0.6.0/selenium/tests/browserbot/pagebot-locator-tests-include.html +33 -0
  111. data/vendor/selenium-0.6.0/selenium/tests/browserbot/pagebot-locator-tests.html +258 -0
  112. data/vendor/selenium-0.6.0/selenium/tests/browserbot/pagebot-property-tests.html +49 -0
  113. data/vendor/selenium-0.6.0/selenium/tests/browserbot/pattern-matcher-tests.html +66 -0
  114. data/vendor/selenium-0.6.0/selenium/tests/browserbot/selenium-api-tests.html +412 -0
  115. data/vendor/selenium-0.6.0/selenium/tests/browserbot/selenium-parameter-tests.html +98 -0
  116. data/vendor/selenium-0.6.0/selenium/tests/browserbot/suite.html +52 -0
  117. data/vendor/selenium-0.6.0/selenium/tests/browserbot/testloop-handle-error-tests.html +74 -0
  118. data/vendor/selenium-0.6.0/selenium/tests/events/TestButtonEvents.html +72 -0
  119. data/vendor/selenium-0.6.0/selenium/tests/events/TestCheckboxEvents.html +107 -0
  120. data/vendor/selenium-0.6.0/selenium/tests/events/TestFireEvents.html +75 -0
  121. data/vendor/selenium-0.6.0/selenium/tests/events/TestLinkEvents.html +43 -0
  122. data/vendor/selenium-0.6.0/selenium/tests/events/TestRadioEvents.html +149 -0
  123. data/vendor/selenium-0.6.0/selenium/tests/events/TestSelectEvents.html +122 -0
  124. data/vendor/selenium-0.6.0/selenium/tests/events/TestTextEvents.html +87 -0
  125. data/vendor/selenium-0.6.0/selenium/tests/events/readme.txt +26 -0
  126. data/vendor/selenium-0.6.0/selenium/tests/html/banner.gif +0 -0
  127. data/vendor/selenium-0.6.0/selenium/tests/html/test_async_event.html +36 -0
  128. data/vendor/selenium-0.6.0/selenium/tests/html/test_click_javascript_page.html +34 -0
  129. data/vendor/selenium-0.6.0/selenium/tests/html/test_click_page1.html +31 -0
  130. data/vendor/selenium-0.6.0/selenium/tests/html/test_click_page2.html +30 -0
  131. data/vendor/selenium-0.6.0/selenium/tests/html/test_confirm.html +34 -0
  132. data/vendor/selenium-0.6.0/selenium/tests/html/test_dummy_page.html +26 -0
  133. data/vendor/selenium-0.6.0/selenium/tests/html/test_editable.html +36 -0
  134. data/vendor/selenium-0.6.0/selenium/tests/html/test_focus_on_blur.html +33 -0
  135. data/vendor/selenium-0.6.0/selenium/tests/html/test_form_events.html +98 -0
  136. data/vendor/selenium-0.6.0/selenium/tests/html/test_framed_page.html +7 -0
  137. data/vendor/selenium-0.6.0/selenium/tests/html/test_just_text.html +22 -0
  138. data/vendor/selenium-0.6.0/selenium/tests/html/test_locators.html +34 -0
  139. data/vendor/selenium-0.6.0/selenium/tests/html/test_modal_dialog.html +29 -0
  140. data/vendor/selenium-0.6.0/selenium/tests/html/test_modal_dialog_dialog.html +35 -0
  141. data/vendor/selenium-0.6.0/selenium/tests/html/test_open.html +23 -0
  142. data/vendor/selenium-0.6.0/selenium/tests/html/test_prompt.html +34 -0
  143. data/vendor/selenium-0.6.0/selenium/tests/html/test_reload_onchange_page.html +32 -0
  144. data/vendor/selenium-0.6.0/selenium/tests/html/test_select.html +35 -0
  145. data/vendor/selenium-0.6.0/selenium/tests/html/test_select_window.html +29 -0
  146. data/vendor/selenium-0.6.0/selenium/tests/html/test_select_window_popup.html +28 -0
  147. data/vendor/selenium-0.6.0/selenium/tests/html/test_slowloading_page.html +27 -0
  148. data/vendor/selenium-0.6.0/selenium/tests/html/test_store_value.html +23 -0
  149. data/vendor/selenium-0.6.0/selenium/tests/html/test_type_page1.html +37 -0
  150. data/vendor/selenium-0.6.0/selenium/tests/html/test_type_page2.html +61 -0
  151. data/vendor/selenium-0.6.0/selenium/tests/html/test_verifications.html +42 -0
  152. data/vendor/selenium-0.6.0/selenium/tests/html/test_verify_alert.html +46 -0
  153. data/vendor/selenium-0.6.0/selenium/tests/html/test_visibility.html +53 -0
  154. data/vendor/selenium-0.6.0/selenium/tests/readme.txt +1 -0
  155. data/vendor/selenium-0.6.0/selenium/tests/tableparser/tableparser-tests.html +122 -0
  156. data/vendor/selenium-0.6.0/selenium/tests/tinyWebServer.py +70 -0
  157. data/vendor/selenium-0.6.0/selenium/user-extensions.js.sample +62 -0
  158. data/vendor/selenium-0.6.0/selenium/version.txt +1 -0
  159. data/vendor/selenium-0.6.0/selenium/xmlextras.js +153 -0
  160. data/vendor/selenium-0.6.0/selenium/xpath.js +3910 -0
  161. metadata +216 -0
@@ -0,0 +1,930 @@
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
+ /*
19
+ * This script provides the Javascript API to drive the test application contained within
20
+ * a Browser Window.
21
+ * TODO:
22
+ * Add support for more events (keyboard and mouse)
23
+ * Allow to switch "user-entry" mode from mouse-based to keyboard-based, firing different
24
+ * events in different modes.
25
+ */
26
+
27
+ // The window to which the commands will be sent. For example, to click on a
28
+ // popup window, first select that window, and then do a normal click command.
29
+
30
+
31
+ // Although it's generally better web development practice not to use browser-detection
32
+ // (feature detection is better), the subtle browser differences that Selenium has to
33
+ // work around seem to make it necessary. Maybe as we learn more about what we need,
34
+ // we can do this in a more "feature-centric" rather than "browser-centric" way.
35
+ // TODO we should probably reuse an available browser-detection library
36
+ var browserName=navigator.appName;
37
+ var isIE = (browserName =="Microsoft Internet Explorer");
38
+ var isKonqueror = (browserName == "Konqueror");
39
+ var isSafari = (navigator.userAgent.indexOf('Safari') != -1);
40
+
41
+ // Get the Gecko version as an 8 digit date.
42
+ var geckoResult = /^Mozilla\/5\.0 .*Gecko\/(\d{8}).*$/.exec(navigator.userAgent);
43
+ var geckoVersion = geckoResult == null ? null : geckoResult[1];
44
+
45
+ BrowserBot = function(frame) {
46
+ this.frame = frame;
47
+ this.currentPage = null;
48
+ this.currentWindowName = null;
49
+
50
+ this.modalDialogTest = null;
51
+ this.recordedAlerts = new Array();
52
+ this.recordedConfirmations = new Array();
53
+ this.recordedPrompts = new Array();
54
+ this.openedWindows = {};
55
+ this.nextConfirmResult = true;
56
+ this.nextPromptResult = '';
57
+ this.newPageLoaded = false;
58
+
59
+ var self = this;
60
+ this.recordPageLoad = function() {
61
+ LOG.debug("Page load detected, location=" + self.getCurrentWindow().location);
62
+ self.currentPage = null;
63
+ self.newPageLoaded = true;
64
+ };
65
+
66
+ this.isNewPageLoaded = function() {
67
+ return self.newPageLoaded;
68
+ };
69
+ };
70
+
71
+ BrowserBot.createForFrame = function(frame) {
72
+ var browserbot;
73
+ if (isIE) {
74
+ browserbot = new IEBrowserBot(frame);
75
+ }
76
+ else if (isKonqueror) {
77
+ browserbot = new KonquerorBrowserBot(frame);
78
+ }
79
+ else if (isSafari) {
80
+ browserbot = new SafariBrowserBot(frame);
81
+ }
82
+ else {
83
+ // Use mozilla by default
84
+ browserbot = new MozillaBrowserBot(frame);
85
+ }
86
+
87
+ // Modify the test IFrame so that page loads are detected.
88
+ addLoadListener(browserbot.getFrame(), browserbot.recordPageLoad);
89
+ return browserbot;
90
+ };
91
+
92
+ BrowserBot.prototype.doModalDialogTest = function(test) {
93
+ this.modalDialogTest = test;
94
+ };
95
+
96
+ BrowserBot.prototype.cancelNextConfirmation = function() {
97
+ this.nextConfirmResult = false;
98
+ };
99
+
100
+ BrowserBot.prototype.setNextPromptResult = function(result) {
101
+ this.nextPromptResult = result;
102
+ };
103
+
104
+ BrowserBot.prototype.hasAlerts = function() {
105
+ return (this.recordedAlerts.length > 0) ;
106
+ };
107
+
108
+ BrowserBot.prototype.getNextAlert = function() {
109
+ return this.recordedAlerts.shift();
110
+ };
111
+
112
+ BrowserBot.prototype.hasConfirmations = function() {
113
+ return (this.recordedConfirmations.length > 0) ;
114
+ };
115
+
116
+ BrowserBot.prototype.getNextConfirmation = function() {
117
+ return this.recordedConfirmations.shift();
118
+ };
119
+
120
+ BrowserBot.prototype.hasPrompts = function() {
121
+ return (this.recordedPrompts.length > 0) ;
122
+ };
123
+
124
+ BrowserBot.prototype.getNextPrompt = function() {
125
+ return this.recordedPrompts.shift();
126
+ };
127
+
128
+ BrowserBot.prototype.getFrame = function() {
129
+ return this.frame;
130
+ };
131
+
132
+ BrowserBot.prototype.selectWindow = function(target) {
133
+ // we've moved to a new page - clear the current one
134
+ this.currentPage = null;
135
+ this.currentWindowName = null;
136
+ if (target && target != "null") {
137
+ // If window exists
138
+ if (this.getTargetWindow(target)) {
139
+ this.currentWindowName = target;
140
+ }
141
+ }
142
+ };
143
+
144
+ BrowserBot.prototype.openLocation = function(target) {
145
+ // We're moving to a new page - clear the current one
146
+ this.currentPage = null;
147
+ this.newPageLoaded = false;
148
+
149
+ this.setIFrameLocation(this.getFrame(), target);
150
+ };
151
+
152
+ BrowserBot.prototype.setIFrameLocation = function(iframe, location) {
153
+ iframe.src = location;
154
+ };
155
+
156
+ BrowserBot.prototype.getCurrentPage = function() {
157
+ if (this.currentPage == null) {
158
+ var testWindow = this.getCurrentWindow();
159
+ this.modifyWindowToRecordPopUpDialogs(testWindow, this);
160
+ this.modifySeparateTestWindowToDetectPageLoads(testWindow);
161
+ this.currentPage = PageBot.createForWindow(testWindow);
162
+ this.newPageLoaded = false;
163
+ }
164
+
165
+ return this.currentPage;
166
+ };
167
+
168
+ BrowserBot.prototype.modifyWindowToRecordPopUpDialogs = function(windowToModify, browserBot) {
169
+ windowToModify.alert = function(alert) {
170
+ browserBot.recordedAlerts.push(alert);
171
+ };
172
+
173
+ windowToModify.confirm = function(message) {
174
+ browserBot.recordedConfirmations.push(message);
175
+ var result = browserBot.nextConfirmResult;
176
+ browserBot.nextConfirmResult = true;
177
+ return result;
178
+ };
179
+
180
+ windowToModify.prompt = function(message) {
181
+ browserBot.recordedPrompts.push(message);
182
+ var result = !browserBot.nextConfirmResult ? null : browserBot.nextPromptResult;
183
+ browserBot.nextConfirmResult = true;
184
+ browserBot.nextPromptResult = '';
185
+ return result;
186
+ };
187
+
188
+ // Keep a reference to all popup windows by name
189
+ // note that in IE the "windowName" argument must be a valid javascript identifier, it seems.
190
+ var originalOpen = windowToModify.open;
191
+ windowToModify.open = function(url, windowName, windowFeatures, replaceFlag) {
192
+ var openedWindow = originalOpen(url, windowName, windowFeatures, replaceFlag);
193
+ selenium.browserbot.openedWindows[windowName] = openedWindow;
194
+ return openedWindow;
195
+ };
196
+ };
197
+
198
+ /**
199
+ * The main IFrame has a single, long-lived onload handler that clears
200
+ * Browserbot.currentPage and sets the "newPageLoaded" flag. For separate
201
+ * windows, we need to attach a handler each time. This uses the
202
+ * "callOnWindowPageTransition" mechanism, which is implemented differently
203
+ * for different browsers.
204
+ */
205
+ BrowserBot.prototype.modifySeparateTestWindowToDetectPageLoads = function(windowToModify) {
206
+ if (this.currentWindowName != null) {
207
+ this.callOnWindowPageTransition(this.recordPageLoad, windowToModify);
208
+ }
209
+ };
210
+
211
+ /**
212
+ * Call the supplied function when a the current page unloads and a new one loads.
213
+ * This is done with an "unload" handler which attaches a "load" handler.
214
+ */
215
+ BrowserBot.prototype.callOnWindowPageTransition = function(loadFunction, windowObject) {
216
+ var attachLoadListener = function() {
217
+ if (windowObject && !windowObject.closed) {
218
+ addLoadListener(windowObject, loadFunction);
219
+ }
220
+ };
221
+
222
+ var unloadFunction = function() {
223
+ window.setTimeout(attachLoadListener, 0);
224
+ };
225
+ addUnloadListener(windowObject, unloadFunction);
226
+ };
227
+
228
+ BrowserBot.prototype.getContentWindow = function() {
229
+ return this.getFrame().contentWindow || frames[this.getFrame().id];
230
+ };
231
+
232
+ BrowserBot.prototype.getTargetWindow = function(windowName) {
233
+ LOG.debug("getTargetWindow(" + windowName + ")");
234
+ // First look in the map of opened windows
235
+ var targetWindow = this.openedWindows[windowName];
236
+ if (!targetWindow) {
237
+ var evalString = "this.getContentWindow().window." + windowName;
238
+ targetWindow = eval(evalString);
239
+ }
240
+ if (!targetWindow) {
241
+ throw new SeleniumError("Window does not exist");
242
+ }
243
+ return targetWindow;
244
+ };
245
+
246
+ BrowserBot.prototype.getCurrentWindow = function() {
247
+ var testWindow = this.getContentWindow().window;
248
+ if (this.currentWindowName != null) {
249
+ testWindow = this.getTargetWindow(this.currentWindowName);
250
+ }
251
+ return testWindow;
252
+ };
253
+
254
+ function MozillaBrowserBot(frame) {
255
+ BrowserBot.call(this, frame);
256
+ }
257
+ MozillaBrowserBot.prototype = new BrowserBot;
258
+
259
+ function KonquerorBrowserBot(frame) {
260
+ BrowserBot.call(this, frame);
261
+ }
262
+ KonquerorBrowserBot.prototype = new BrowserBot;
263
+
264
+ KonquerorBrowserBot.prototype.setIFrameLocation = function(iframe, location) {
265
+ // Window doesn't fire onload event when setting src to the current value,
266
+ // so we set it to blank first.
267
+ iframe.src = "about:blank";
268
+ iframe.src = location;
269
+ };
270
+
271
+ /**
272
+ * Call the supplied function when a the current page unloads and a new one loads.
273
+ * This is done by polling continuously until the document changes and is fully loaded.
274
+ */
275
+ KonquerorBrowserBot.prototype.callOnWindowPageTransition = function(loadFunction, windowObject) {
276
+ // Since the unload event doesn't fire in Safari 1.3, we start polling immediately
277
+ // This works in Konqueror as well
278
+ if (windowObject && !windowObject.closed) {
279
+ LOG.debug("Starting pollForLoad");
280
+ this.pollForLoad(loadFunction, windowObject, windowObject.document);
281
+ }
282
+ };
283
+
284
+ /**
285
+ * For Konqueror (and Safari), we can't catch the onload event for a separate window (as opposed to an IFrame)
286
+ * So we set up a polling timer that will keep checking the readyState of the document until it's complete.
287
+ * Since we might call this before the original page is unloaded, we check to see that the completed document
288
+ * is different from the original one.
289
+ */
290
+ KonquerorBrowserBot.prototype.pollForLoad = function(loadFunction, windowObject, originalDocument) {
291
+ if (windowObject.closed) {
292
+ return;
293
+ }
294
+
295
+ var sameDoc = (originalDocument === windowObject.document);
296
+ var rs = windowObject.document.readyState;
297
+
298
+ if (!sameDoc && rs == 'complete') {
299
+ LOG.debug("pollForLoad complete: " + rs + " (" + sameDoc + ")");
300
+ loadFunction();
301
+ return;
302
+ }
303
+ var self = this;
304
+ LOG.debug("pollForLoad continue");
305
+ window.setTimeout(function() {self.pollForLoad(loadFunction, windowObject, originalDocument);}, 500);
306
+ };
307
+
308
+ function SafariBrowserBot(frame) {
309
+ BrowserBot.call(this, frame);
310
+ }
311
+ SafariBrowserBot.prototype = new BrowserBot;
312
+
313
+ SafariBrowserBot.prototype.setIFrameLocation = KonquerorBrowserBot.prototype.setIFrameLocation;
314
+ SafariBrowserBot.prototype.callOnWindowPageTransition = KonquerorBrowserBot.prototype.callOnWindowPageTransition;
315
+ SafariBrowserBot.prototype.pollForLoad = KonquerorBrowserBot.prototype.pollForLoad;
316
+
317
+ function IEBrowserBot(frame) {
318
+ BrowserBot.call(this, frame);
319
+ }
320
+ IEBrowserBot.prototype = new BrowserBot;
321
+ IEBrowserBot.prototype.callOnWindowPageTransition = KonquerorBrowserBot.prototype.callOnWindowPageTransition;
322
+ IEBrowserBot.prototype.pollForLoad = KonquerorBrowserBot.prototype.pollForLoad;
323
+
324
+ IEBrowserBot.prototype.modifyWindowToRecordPopUpDialogs = function(windowToModify, browserBot) {
325
+ BrowserBot.prototype.modifyWindowToRecordPopUpDialogs(windowToModify, browserBot);
326
+
327
+ // we will call the previous version of this method from within our own interception
328
+ oldShowModalDialog = windowToModify.showModalDialog;
329
+
330
+ windowToModify.showModalDialog = function(url, args, features) {
331
+ // Get relative directory to where TestRunner.html lives
332
+ // A risky assumption is that the user's TestRunner is named TestRunner.html
333
+ var doc_location = document.location.toString();
334
+ var end_of_base_ref = doc_location.indexOf('TestRunner.html');
335
+ var base_ref = doc_location.substring(0, end_of_base_ref);
336
+
337
+ var fullURL = base_ref + "TestRunner.html?singletest=" + escape(browserBot.modalDialogTest) + "&autoURL=" + escape(url) + "&runInterval=" + runInterval;
338
+ browserBot.modalDialogTest = null;
339
+
340
+ var returnValue = oldShowModalDialog(fullURL, args, features);
341
+ return returnValue;
342
+ };
343
+ };
344
+
345
+ SafariBrowserBot.prototype.modifyWindowToRecordPopUpDialogs = function(windowToModify, browserBot) {
346
+ BrowserBot.prototype.modifyWindowToRecordPopUpDialogs(windowToModify, browserBot);
347
+
348
+ var originalOpen = windowToModify.open;
349
+ /*
350
+ * Safari seems to be broken, so that when we manually trigger the onclick method
351
+ * of a button/href, any window.open calls aren't resolved relative to the app location.
352
+ * So here we replace the open() method with one that does resolve the url correctly.
353
+ */
354
+ windowToModify.open = function(url, windowName, windowFeatures, replaceFlag) {
355
+
356
+ if (url.startsWith("http://") || url.startsWith("https://") || url.startsWith("/")) {
357
+ return originalOpen(url, windowName, windowFeatures, replaceFlag);
358
+ }
359
+
360
+ // Reduce the current path to the directory
361
+ var currentPath = windowToModify.location.pathname || "/";
362
+ currentPath = currentPath.replace(/\/[^\/]*$/, "/");
363
+
364
+ // Remove any leading "./" from the new url.
365
+ url = url.replace(/^\.\//, "");
366
+
367
+ newUrl = currentPath + url;
368
+
369
+ return originalOpen(newUrl, windowName, windowFeatures, replaceFlag);
370
+ };
371
+ };
372
+
373
+ PageBot = function(pageWindow) {
374
+ if (pageWindow) {
375
+ this.currentWindow = pageWindow;
376
+ this.currentDocument = pageWindow.document;
377
+ this.location = pageWindow.location;
378
+ this.title = function() {return this.currentDocument.title;};
379
+ }
380
+
381
+ // Register all locateElementBy* functions
382
+ // TODO - don't do this in the constructor - only needed once ever
383
+ this.locationStrategies = {};
384
+ for (var functionName in this) {
385
+ var result = /^locateElementBy([A-Z].+)$/.exec(functionName);
386
+ if (result != null) {
387
+ var locatorFunction = this[functionName];
388
+ if (typeof(locatorFunction) != 'function') {
389
+ continue;
390
+ }
391
+ // Use a specified prefix in preference to one generated from
392
+ // the function name
393
+ var locatorPrefix = locatorFunction.prefix || result[1].toLowerCase();
394
+ this.locationStrategies[locatorPrefix] = locatorFunction;
395
+ }
396
+ }
397
+
398
+ /**
399
+ * Find a locator based on a prefix.
400
+ */
401
+ this.findElementBy = function(locatorType, locator, inDocument) {
402
+ var locatorFunction = this.locationStrategies[locatorType];
403
+ if (! locatorFunction) {
404
+ throw new SeleniumError("Unrecognised locator type: '" + locatorType + "'");
405
+ }
406
+ return locatorFunction.call(this, locator, inDocument);
407
+ };
408
+
409
+ /**
410
+ * The implicit locator, that is used when no prefix is supplied.
411
+ */
412
+ this.locationStrategies['implicit'] = function(locator, inDocument) {
413
+ if (locator.startsWith('//')) {
414
+ return this.locateElementByXPath(locator, inDocument);
415
+ }
416
+ if (locator.startsWith('document.')) {
417
+ return this.locateElementByDomTraversal(locator, inDocument);
418
+ }
419
+ return this.locateElementByIdentifier(locator, inDocument);
420
+ };
421
+
422
+ };
423
+
424
+ PageBot.createForWindow = function(windowObject) {
425
+ if (isIE) {
426
+ return new IEPageBot(windowObject);
427
+ }
428
+ else if (isKonqueror) {
429
+ return new KonquerorPageBot(windowObject);
430
+ }
431
+ else if (isSafari) {
432
+ return new SafariPageBot(windowObject);
433
+ }
434
+ else {
435
+ // Use mozilla by default
436
+ return new MozillaPageBot(windowObject);
437
+ }
438
+ };
439
+
440
+ MozillaPageBot = function(pageWindow) {
441
+ PageBot.call(this, pageWindow);
442
+ };
443
+ MozillaPageBot.prototype = new PageBot();
444
+
445
+ KonquerorPageBot = function(pageWindow) {
446
+ PageBot.call(this, pageWindow);
447
+ };
448
+ KonquerorPageBot.prototype = new PageBot();
449
+
450
+ SafariPageBot = function(pageWindow) {
451
+ PageBot.call(this, pageWindow);
452
+ };
453
+ SafariPageBot.prototype = new PageBot();
454
+
455
+ IEPageBot = function(pageWindow) {
456
+ PageBot.call(this, pageWindow);
457
+ };
458
+ IEPageBot.prototype = new PageBot();
459
+
460
+ /*
461
+ * Finds an element on the current page, using various lookup protocols
462
+ */
463
+ PageBot.prototype.findElement = function(locator) {
464
+ var locatorType = 'implicit';
465
+ var locatorString = locator;
466
+
467
+ // If there is a locator prefix, use the specified strategy
468
+ var result = locator.match(/^([A-Za-z]+)=(.+)/);
469
+ if (result) {
470
+ locatorType = result[1].toLowerCase();
471
+ locatorString = result[2];
472
+ }
473
+
474
+ var element = this.findElementBy(locatorType, locatorString, this.currentDocument);
475
+ if (element != null) {
476
+ return element;
477
+ }
478
+ for (var i = 0; i < this.currentWindow.frames.length; i++) {
479
+ element = this.findElementBy(locatorType, locatorString, this.currentWindow.frames[i].document);
480
+ if (element != null) {
481
+ return element;
482
+ }
483
+ }
484
+
485
+ // Element was not found by any locator function.
486
+ throw new SeleniumError("Element " + locator + " not found");
487
+ };
488
+
489
+ /**
490
+ * In non-IE browsers, getElementById() does not search by name. Instead, we
491
+ * we search separately by id and name.
492
+ */
493
+ PageBot.prototype.locateElementByIdentifier = function(identifier, inDocument) {
494
+ return PageBot.prototype.locateElementById(identifier, inDocument)
495
+ || PageBot.prototype.locateElementByName(identifier, inDocument)
496
+ || null;
497
+ };
498
+
499
+ /**
500
+ * In IE, getElementById() also searches by name - this is an optimisation for IE.
501
+ */
502
+ IEPageBot.prototype.locateElementByIdentifer = function(identifier, inDocument) {
503
+ return inDocument.getElementById(identifier);
504
+ };
505
+
506
+ /**
507
+ * Find the element with id - can't rely on getElementById, coz it returns by name as well in IE..
508
+ */
509
+ PageBot.prototype.locateElementById = function(identifier, inDocument) {
510
+ var element = inDocument.getElementById(identifier);
511
+ if (element && element.id === identifier) {
512
+ return element;
513
+ }
514
+ else {
515
+ return null;
516
+ }
517
+ };
518
+
519
+ /**
520
+ * In regular browsers, getElementById() does not search by name.
521
+ * We search by @name using XPath, or by checking every element.
522
+ */
523
+ PageBot.prototype.locateElementByName = function(identifier, inDocument) {
524
+ var allElements = inDocument.getElementsByTagName("*");
525
+ for (var i = 0; i < allElements.length; i++) {
526
+ var testElement = allElements[i];
527
+ if (testElement.name && testElement.name === identifier) {
528
+ return testElement;
529
+ }
530
+ }
531
+ return null;
532
+ };
533
+
534
+ /**
535
+ * Finds an element using by evaluating the "document.*" string against the
536
+ * current document object. Dom expressions must begin with "document."
537
+ */
538
+ PageBot.prototype.locateElementByDomTraversal = function(domTraversal, inDocument) {
539
+ if (domTraversal.indexOf("document.") != 0) {
540
+ return null;
541
+ }
542
+
543
+ // Trim the leading 'document'
544
+ domTraversal = domTraversal.substr(9);
545
+ var locatorScript = "inDocument." + domTraversal;
546
+ var element = eval(locatorScript);
547
+
548
+ if (!element) {
549
+ return null;
550
+ }
551
+
552
+ return element;
553
+ };
554
+ PageBot.prototype.locateElementByDomTraversal.prefix = "dom";
555
+
556
+ /**
557
+ * Finds an element identified by the xpath expression. Expressions _must_
558
+ * begin with "//".
559
+ */
560
+ PageBot.prototype.locateElementByXPath = function(xpath, inDocument) {
561
+
562
+ // Trim any trailing "/": not valid xpath, and remains from attribute
563
+ // locator.
564
+ if (xpath.charAt(xpath.length - 1) == '/') {
565
+ xpath = xpath.slice(0, -1);
566
+ }
567
+
568
+ // Handle //tag
569
+ var match = xpath.match(/^\/\/(\w+|\*)$/);
570
+ if (match) {
571
+ var elements = inDocument.getElementsByTagName(match[1].toUpperCase());
572
+ if (elements == null) return null;
573
+ return elements[0];
574
+ }
575
+
576
+ // Handle //tag[@attr='value']
577
+ var match = xpath.match(/^\/\/(\w+|\*)\[@(\w+)=('([^\']+)'|"([^\"]+)")\]$/);
578
+ if (match) {
579
+ return this.findElementByTagNameAndAttributeValue(
580
+ inDocument,
581
+ match[1].toUpperCase(),
582
+ match[2].toLowerCase(),
583
+ match[3].slice(1, -1)
584
+ );
585
+ }
586
+
587
+ // Handle //tag[text()='value']
588
+ var match = xpath.match(/^\/\/(\w+|\*)\[text\(\)=('([^\']+)'|"([^\"]+)")\]$/);
589
+ if (match) {
590
+ return this.findElementByTagNameAndText(
591
+ inDocument,
592
+ match[1].toUpperCase(),
593
+ match[2].slice(1, -1)
594
+ );
595
+ }
596
+
597
+ return this.findElementUsingFullXPath(xpath, inDocument);
598
+ };
599
+
600
+ PageBot.prototype.findElementByTagNameAndAttributeValue = function(
601
+ inDocument, tagName, attributeName, attributeValue
602
+ ) {
603
+ if (isIE && attributeName == "class") {
604
+ attributeName = "className";
605
+ }
606
+ var elements = inDocument.getElementsByTagName(tagName);
607
+ for (var i = 0; i < elements.length; i++) {
608
+ var elementAttr = elements[i].getAttribute(attributeName);
609
+ if (elementAttr == attributeValue) {
610
+ return elements[i];
611
+ }
612
+ }
613
+ return null;
614
+ };
615
+
616
+ PageBot.prototype.findElementByTagNameAndText = function(
617
+ inDocument, tagName, text
618
+ ) {
619
+ var elements = inDocument.getElementsByTagName(tagName);
620
+ for (var i = 0; i < elements.length; i++) {
621
+ if (getText(elements[i]) == text) {
622
+ return elements[i];
623
+ }
624
+ }
625
+ return null;
626
+ };
627
+
628
+ PageBot.prototype.findElementUsingFullXPath = function(xpath, inDocument) {
629
+ if (isIE && !inDocument.evaluate) {
630
+ addXPathSupport(inDocument);
631
+ }
632
+
633
+ // Use document.evaluate() if it's available
634
+ if (inDocument.evaluate) {
635
+ return inDocument.evaluate(xpath, inDocument, null, 0, null).iterateNext();
636
+ }
637
+
638
+ // If not, fall back to slower JavaScript implementation
639
+ var context = new XPathContext();
640
+ context.expressionContextNode = inDocument;
641
+ var xpathResult = new XPathParser().parse(xpath).evaluate(context);
642
+ if (xpathResult && xpathResult.toArray) {
643
+ return xpathResult.toArray()[0];
644
+ }
645
+ return null;
646
+ };
647
+
648
+ /**
649
+ * Finds a link element with text matching the expression supplied. Expressions must
650
+ * begin with "link:".
651
+ */
652
+ PageBot.prototype.locateElementByLinkText = function(linkText, inDocument) {
653
+ var links = inDocument.getElementsByTagName('a');
654
+ for (var i = 0; i < links.length; i++) {
655
+ var element = links[i];
656
+ if (PatternMatcher.matches(linkText, getText(element))) {
657
+ return element;
658
+ }
659
+ }
660
+ return null;
661
+ };
662
+ PageBot.prototype.locateElementByLinkText.prefix = "link";
663
+
664
+ /**
665
+ * Returns an attribute based on an attribute locator. This is made up of an element locator
666
+ * suffixed with @attribute-name.
667
+ */
668
+ PageBot.prototype.findAttribute = function(locator) {
669
+ // Split into locator + attributeName
670
+ var attributePos = locator.lastIndexOf("@");
671
+ var elementLocator = locator.slice(0, attributePos);
672
+ var attributeName = locator.slice(attributePos + 1);
673
+
674
+ // Find the element.
675
+ var element = this.findElement(elementLocator);
676
+
677
+ // Handle missing "class" attribute in IE.
678
+ if (isIE && attributeName == "class") {
679
+ attributeName = "className";
680
+ }
681
+
682
+ // Get the attribute value.
683
+ var attributeValue = element.getAttribute(attributeName);
684
+
685
+ return attributeValue ? attributeValue.toString() : null;
686
+ };
687
+
688
+ /*
689
+ * Select the specified option and trigger the relevant events of the element.
690
+ */
691
+ PageBot.prototype.selectOption = function(element, option) {
692
+ triggerEvent(element, 'focus', false);
693
+ if (!option.selected) {
694
+ option.selected = true;
695
+ triggerEvent(element, 'change', true);
696
+ }
697
+ triggerEvent(element, 'blur', false);
698
+ };
699
+
700
+ PageBot.prototype.replaceText = function(element, stringValue) {
701
+ triggerEvent(element, 'focus', false);
702
+ triggerEvent(element, 'select', true);
703
+ element.value=stringValue;
704
+ triggerEvent(element, 'change', true);
705
+ triggerEvent(element, 'blur', false);
706
+ };
707
+
708
+ MozillaPageBot.prototype.clickElement = function(element) {
709
+
710
+ triggerEvent(element, 'focus', false);
711
+
712
+ // Add an event listener that detects if the default action has been prevented.
713
+ // (This is caused by a javascript onclick handler returning false)
714
+ var preventDefault = false;
715
+ if (geckoVersion) {
716
+ element.addEventListener("click", function(evt) {preventDefault = evt.getPreventDefault();}, false);
717
+ }
718
+
719
+ // Trigger the click event.
720
+ triggerMouseEvent(element, 'click', true);
721
+
722
+ // In FireFox < 1.0 Final, and Mozilla <= 1.7.3, just sending the click event is enough.
723
+ // But in newer versions, we need to do it ourselves.
724
+ var needsProgrammaticClick = (geckoVersion > '20041025');
725
+ // Perform the link action if preventDefault was set.
726
+ if (needsProgrammaticClick && !preventDefault) {
727
+ // Try the element itself, as well as it's parent - this handles clicking images inside links.
728
+ if (element.href) {
729
+ this.currentWindow.location.href = element.href;
730
+ }
731
+ else if (element.parentNode.href) {
732
+ this.currentWindow.location.href = element.parentNode.href;
733
+ }
734
+ }
735
+
736
+ if (this.windowClosed()) {
737
+ return;
738
+ }
739
+
740
+ triggerEvent(element, 'blur', false);
741
+ };
742
+
743
+ KonquerorPageBot.prototype.clickElement = function(element) {
744
+
745
+ triggerEvent(element, 'focus', false);
746
+
747
+ if (element.click) {
748
+ element.click();
749
+ }
750
+ else {
751
+ triggerMouseEvent(element, 'click', true);
752
+ }
753
+
754
+ if (this.windowClosed()) {
755
+ return;
756
+ }
757
+
758
+ triggerEvent(element, 'blur', false);
759
+ };
760
+
761
+ SafariPageBot.prototype.clickElement = function(element) {
762
+
763
+ triggerEvent(element, 'focus', false);
764
+
765
+ var wasChecked = element.checked;
766
+
767
+ // For form element it is simple.
768
+ if (element.click) {
769
+ element.click();
770
+ }
771
+ // For links and other elements, event emulation is required.
772
+ else {
773
+ triggerEvent(element, 'click', true);
774
+
775
+ // Unfortunately, triggering the event doesn't seem to activate onclick handlers.
776
+ // We currently call onclick for the link, but I'm guessing that the onclick for containing
777
+ // elements is not being called.
778
+ var success = true;
779
+ if (element.onclick) {
780
+ var evt = document.createEvent('HTMLEvents');
781
+ evt.initEvent('click', true, true);
782
+ var onclickResult = element.onclick(evt);
783
+ if (onclickResult === false) {
784
+ success = false;
785
+ }
786
+ }
787
+
788
+ if (success) {
789
+ // Try the element itself, as well as it's parent - this handles clicking images inside links.
790
+ if (element.href) {
791
+ this.currentWindow.location.href = element.href;
792
+ }
793
+ else if (element.parentNode.href) {
794
+ this.currentWindow.location.href = element.parentNode.href;
795
+ } else {
796
+ // This is true for buttons outside of forms, and maybe others.
797
+ LOG.warn("Ignoring 'click' call for button outside form, or link without href."
798
+ + "Using buttons without an enclosing form can cause wierd problems with URL resolution in Safari." );
799
+ // I implemented special handling for window.open, but unfortunately this behaviour is also displayed
800
+ // when we have a button without an enclosing form that sets document.location in the onclick handler.
801
+ // The solution is to always use an enclosing form for a button.
802
+ }
803
+ }
804
+ }
805
+
806
+ // Onchange event is not triggered automatically in Safari.
807
+ if (isDefined(element.checked) && wasChecked != element.checked) {
808
+ triggerEvent(element, 'change', true);
809
+ }
810
+
811
+ if (this.windowClosed()) {
812
+ return;
813
+ }
814
+
815
+ triggerEvent(element, 'blur', false);
816
+ };
817
+
818
+ IEPageBot.prototype.clickElement = function(element) {
819
+
820
+ triggerEvent(element, 'focus', false);
821
+
822
+ var wasChecked = element.checked;
823
+
824
+ // Set a flag that records if the page will unload - this isn't always accurate, because
825
+ // <a href="javascript:alert('foo'):"> triggers the onbeforeunload event, even thought the page won't unload
826
+ var pageUnloading = false;
827
+ var pageUnloadDetector = function() {pageUnloading = true;};
828
+ this.currentWindow.attachEvent("onbeforeunload", pageUnloadDetector);
829
+
830
+ element.click();
831
+
832
+ // If the page is going to unload - still attempt to fire any subsequent events.
833
+ // However, we can't guarantee that the page won't unload half way through, so we need to handle exceptions.
834
+ try {
835
+ this.currentWindow.detachEvent("onbeforeunload", pageUnloadDetector);
836
+
837
+ if (this.windowClosed()) {
838
+ return;
839
+ }
840
+
841
+ // Onchange event is not triggered automatically in IE.
842
+ if (isDefined(element.checked) && wasChecked != element.checked) {
843
+ triggerEvent(element, 'change', true);
844
+ }
845
+
846
+ triggerEvent(element, 'blur', false);
847
+ }
848
+ catch (e) {
849
+ // If the page is unloading, we may get a "Permission denied" or "Unspecified error".
850
+ // Just ignore it, because the document may have unloaded.
851
+ if (pageUnloading) {
852
+ LOG.warn("Caught exception when firing events on unloading page: " + e.message);
853
+ return;
854
+ }
855
+ throw e;
856
+ }
857
+ };
858
+
859
+ PageBot.prototype.windowClosed = function(element) {
860
+ return this.currentWindow.closed;
861
+ };
862
+
863
+ PageBot.prototype.bodyText = function() {
864
+ return getText(this.currentDocument.body);
865
+ };
866
+
867
+ PageBot.prototype.getAllButtons = function() {
868
+ var elements = this.currentDocument.getElementsByTagName('input');
869
+ var result = '';
870
+
871
+ for (var i = 0; i < elements.length; i++) {
872
+ if (elements[i].type == 'button' || elements[i].type == 'submit' || elements[i].type == 'reset') {
873
+ result += elements[i].id;
874
+
875
+ result += ',';
876
+ }
877
+ }
878
+
879
+ return result;
880
+ };
881
+
882
+
883
+ PageBot.prototype.getAllFields = function() {
884
+ var elements = this.currentDocument.getElementsByTagName('input');
885
+ var result = '';
886
+
887
+ for (var i = 0; i < elements.length; i++) {
888
+ if (elements[i].type == 'text') {
889
+ result += elements[i].id;
890
+
891
+ result += ',';
892
+ }
893
+ }
894
+
895
+ return result;
896
+ };
897
+
898
+ PageBot.prototype.getAllLinks = function() {
899
+ var elements = this.currentDocument.getElementsByTagName('a');
900
+ var result = '';
901
+
902
+ for (var i = 0; i < elements.length; i++) {
903
+ result += elements[i].id;
904
+
905
+ result += ',';
906
+ }
907
+
908
+ return result;
909
+ };
910
+
911
+ PageBot.prototype.setContext = function(strContext) {
912
+ //set the current test title
913
+ context.innerHTML=strContext;
914
+ };
915
+
916
+ function isDefined(value) {
917
+ return typeof(value) != undefined;
918
+ }
919
+
920
+ PageBot.prototype.goBack = function() {
921
+ this.currentWindow.history.back();
922
+ };
923
+
924
+ PageBot.prototype.goForward = function() {
925
+ this.currentWindow.history.forward();
926
+ };
927
+
928
+ PageBot.prototype.close = function() {
929
+ this.currentWindow.close();
930
+ };