selenium-webdriver 2.53.4 → 3.8.0
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.
- checksums.yaml +7 -0
- data/CHANGES +363 -10
- data/LICENSE +1 -1
- data/README.md +2 -3
- data/lib/selenium-webdriver.rb +0 -2
- data/lib/selenium/server.rb +69 -70
- data/lib/selenium/webdriver.rb +32 -23
- data/lib/selenium/webdriver/atoms.rb +18 -0
- data/lib/selenium/webdriver/atoms/getAttribute.js +8 -0
- data/lib/selenium/webdriver/chrome.rb +8 -6
- data/lib/selenium/webdriver/chrome/driver.rb +112 -0
- data/lib/selenium/webdriver/chrome/options.rb +168 -0
- data/lib/selenium/webdriver/chrome/profile.rb +17 -17
- data/lib/selenium/webdriver/chrome/service.rb +22 -89
- data/lib/selenium/webdriver/common.rb +13 -6
- data/lib/selenium/webdriver/common/action_builder.rb +49 -57
- data/lib/selenium/webdriver/common/alert.rb +5 -15
- data/lib/selenium/webdriver/common/bridge_helper.rb +10 -17
- data/lib/selenium/webdriver/common/driver.rb +53 -68
- data/lib/selenium/webdriver/common/driver_extensions/{has_input_devices.rb → has_addons.rb} +13 -23
- data/lib/selenium/webdriver/common/driver_extensions/has_location.rb +4 -8
- data/lib/selenium/webdriver/common/driver_extensions/has_network_connection.rb +4 -7
- data/lib/selenium/webdriver/common/driver_extensions/has_remote_status.rb +0 -4
- data/lib/selenium/webdriver/common/driver_extensions/has_session_id.rb +0 -4
- data/lib/selenium/webdriver/common/driver_extensions/has_touch_screen.rb +1 -5
- data/lib/selenium/webdriver/common/driver_extensions/has_web_storage.rb +0 -5
- data/lib/selenium/webdriver/common/driver_extensions/rotatable.rb +4 -9
- data/lib/selenium/webdriver/common/driver_extensions/takes_screenshot.rb +7 -7
- data/lib/selenium/webdriver/common/driver_extensions/uploads_files.rb +2 -7
- data/lib/selenium/webdriver/common/element.rb +57 -39
- data/lib/selenium/webdriver/common/error.rb +204 -106
- data/lib/selenium/webdriver/common/file_reaper.rb +3 -11
- data/lib/selenium/webdriver/common/html5/local_storage.rb +6 -10
- data/lib/selenium/webdriver/common/html5/session_storage.rb +6 -10
- data/lib/selenium/webdriver/common/html5/shared_web_storage.rb +7 -18
- data/lib/selenium/webdriver/{safari/options.rb → common/interactions/input_device.rb} +20 -31
- data/lib/selenium/webdriver/common/interactions/interaction.rb +50 -0
- data/lib/selenium/webdriver/{safari/browser.rb → common/interactions/interactions.rb} +16 -15
- data/lib/selenium/webdriver/common/interactions/key_actions.rb +143 -0
- data/lib/selenium/webdriver/common/interactions/key_input.rb +62 -0
- data/lib/selenium/webdriver/{android.rb → common/interactions/none_input.rb} +11 -6
- data/lib/selenium/webdriver/common/interactions/pointer_actions.rb +353 -0
- data/lib/selenium/webdriver/common/interactions/pointer_input.rb +132 -0
- data/lib/selenium/webdriver/common/keyboard.rb +7 -14
- data/lib/selenium/webdriver/common/keys.rb +99 -82
- data/lib/selenium/webdriver/common/log_entry.rb +3 -6
- data/lib/selenium/webdriver/common/logger.rb +140 -0
- data/lib/selenium/webdriver/common/logs.rb +2 -6
- data/lib/selenium/webdriver/common/mouse.rb +9 -14
- data/lib/selenium/webdriver/common/navigation.rb +2 -6
- data/lib/selenium/webdriver/common/options.rb +20 -23
- data/lib/selenium/webdriver/common/platform.rb +70 -97
- data/lib/selenium/webdriver/common/port_prober.rb +3 -4
- data/lib/selenium/webdriver/common/profile_helper.rb +6 -11
- data/lib/selenium/webdriver/common/proxy.rb +58 -72
- data/lib/selenium/webdriver/common/search_context.rb +22 -29
- data/lib/selenium/webdriver/common/service.rb +161 -0
- data/lib/selenium/webdriver/common/socket_lock.rb +6 -14
- data/lib/selenium/webdriver/common/socket_poller.rb +5 -12
- data/lib/selenium/webdriver/common/target_locator.rb +11 -15
- data/lib/selenium/webdriver/common/timeouts.rb +4 -8
- data/lib/selenium/webdriver/common/touch_action_builder.rb +2 -6
- data/lib/selenium/webdriver/common/touch_screen.rb +19 -23
- data/lib/selenium/webdriver/common/w3c_action_builder.rb +209 -0
- data/lib/selenium/webdriver/{phantomjs.rb → common/w3c_options.rb} +16 -14
- data/lib/selenium/webdriver/common/wait.rb +6 -13
- data/lib/selenium/webdriver/common/window.rb +48 -17
- data/lib/selenium/webdriver/common/zipper.rb +6 -10
- data/lib/selenium/webdriver/edge.rb +5 -12
- data/lib/selenium/webdriver/edge/bridge.rb +32 -63
- data/lib/selenium/webdriver/edge/driver.rb +73 -0
- data/lib/selenium/webdriver/edge/service.rb +18 -87
- data/lib/selenium/webdriver/firefox.rb +20 -11
- data/lib/selenium/webdriver/firefox/binary.rb +40 -56
- data/lib/selenium/webdriver/firefox/driver.rb +48 -0
- data/lib/selenium/webdriver/firefox/extension.rb +18 -8
- data/lib/selenium/webdriver/firefox/extension/prefs.json +3 -11
- data/lib/selenium/webdriver/firefox/extension/webdriver.xpi +0 -0
- data/lib/selenium/webdriver/firefox/launcher.rb +13 -22
- data/lib/selenium/webdriver/firefox/legacy/driver.rb +79 -0
- data/lib/selenium/webdriver/{iphone.rb → firefox/marionette/bridge.rb} +25 -6
- data/lib/selenium/webdriver/firefox/marionette/driver.rb +96 -0
- data/lib/selenium/webdriver/firefox/options.rb +149 -0
- data/lib/selenium/webdriver/firefox/profile.rb +46 -46
- data/lib/selenium/webdriver/firefox/profiles_ini.rb +8 -18
- data/lib/selenium/webdriver/firefox/service.rb +23 -83
- data/lib/selenium/webdriver/firefox/util.rb +0 -4
- data/lib/selenium/webdriver/ie.rb +4 -8
- data/lib/selenium/webdriver/ie/driver.rb +90 -0
- data/lib/selenium/webdriver/ie/options.rb +136 -0
- data/lib/selenium/webdriver/ie/service.rb +58 -0
- data/lib/selenium/webdriver/remote.rb +8 -16
- data/lib/selenium/webdriver/remote/bridge.rb +96 -565
- data/lib/selenium/webdriver/remote/capabilities.rb +76 -94
- data/lib/selenium/webdriver/remote/driver.rb +49 -0
- data/lib/selenium/webdriver/remote/http/common.rb +22 -20
- data/lib/selenium/webdriver/remote/http/curb.rb +9 -12
- data/lib/selenium/webdriver/remote/http/default.rb +54 -41
- data/lib/selenium/webdriver/remote/http/persistent.rb +9 -8
- data/lib/selenium/webdriver/remote/oss/bridge.rb +586 -0
- data/lib/selenium/webdriver/remote/oss/commands.rb +221 -0
- data/lib/selenium/webdriver/remote/response.rb +39 -27
- data/lib/selenium/webdriver/remote/server_error.rb +1 -5
- data/lib/selenium/webdriver/remote/w3c/bridge.rb +573 -0
- data/lib/selenium/webdriver/remote/w3c/capabilities.rb +290 -0
- data/lib/selenium/webdriver/remote/w3c/commands.rb +148 -0
- data/lib/selenium/webdriver/safari.rb +20 -29
- data/lib/selenium/webdriver/{firefox/w3c_bridge.rb → safari/driver.rb} +21 -30
- data/lib/selenium/webdriver/safari/service.rb +57 -0
- data/lib/selenium/webdriver/support.rb +1 -2
- data/lib/selenium/webdriver/support/abstract_event_listener.rb +17 -4
- data/lib/selenium/webdriver/support/block_event_listener.rb +1 -5
- data/lib/selenium/webdriver/support/color.rb +57 -42
- data/lib/selenium/webdriver/support/escaper.rb +41 -0
- data/lib/selenium/webdriver/support/event_firing_bridge.rb +36 -40
- data/lib/selenium/webdriver/support/select.rb +33 -86
- data/selenium-webdriver.gemspec +22 -25
- metadata +254 -261
- data/lib/selenium-client.rb +0 -21
- data/lib/selenium/client.rb +0 -57
- data/lib/selenium/client/base.rb +0 -151
- data/lib/selenium/client/driver.rb +0 -29
- data/lib/selenium/client/errors.rb +0 -28
- data/lib/selenium/client/extensions.rb +0 -132
- data/lib/selenium/client/idiomatic.rb +0 -507
- data/lib/selenium/client/javascript_expression_builder.rb +0 -135
- data/lib/selenium/client/javascript_frameworks/jquery.rb +0 -32
- data/lib/selenium/client/javascript_frameworks/prototype.rb +0 -32
- data/lib/selenium/client/legacy_driver.rb +0 -1722
- data/lib/selenium/client/protocol.rb +0 -123
- data/lib/selenium/client/selenium_helper.rb +0 -49
- data/lib/selenium/rake/server_task.rb +0 -176
- data/lib/selenium/webdriver/android/bridge.rb +0 -68
- data/lib/selenium/webdriver/chrome/bridge.rb +0 -139
- data/lib/selenium/webdriver/common/core_ext/base64.rb +0 -28
- data/lib/selenium/webdriver/common/core_ext/dir.rb +0 -61
- data/lib/selenium/webdriver/common/html5/location.rb +0 -19
- data/lib/selenium/webdriver/common/w3c_error.rb +0 -194
- data/lib/selenium/webdriver/edge/legacy_support.rb +0 -117
- data/lib/selenium/webdriver/firefox/bridge.rb +0 -89
- data/lib/selenium/webdriver/ie/bridge.rb +0 -88
- data/lib/selenium/webdriver/ie/server.rb +0 -133
- data/lib/selenium/webdriver/iphone/bridge.rb +0 -64
- data/lib/selenium/webdriver/phantomjs/bridge.rb +0 -78
- data/lib/selenium/webdriver/phantomjs/service.rb +0 -130
- data/lib/selenium/webdriver/remote/commands.rb +0 -211
- data/lib/selenium/webdriver/remote/w3c_bridge.rb +0 -668
- data/lib/selenium/webdriver/remote/w3c_capabilities.rb +0 -236
- data/lib/selenium/webdriver/remote/w3c_commands.rb +0 -132
- data/lib/selenium/webdriver/safari/bridge.rb +0 -135
- data/lib/selenium/webdriver/safari/resources/client.js +0 -7255
- data/lib/selenium/webdriver/safari/server.rb +0 -187
|
@@ -1,211 +0,0 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
#
|
|
3
|
-
# Licensed to the Software Freedom Conservancy (SFC) under one
|
|
4
|
-
# or more contributor license agreements. See the NOTICE file
|
|
5
|
-
# distributed with this work for additional information
|
|
6
|
-
# regarding copyright ownership. The SFC licenses this file
|
|
7
|
-
# to you under the Apache License, Version 2.0 (the
|
|
8
|
-
# "License"); you may not use this file except in compliance
|
|
9
|
-
# with the License. You may obtain a copy of the License at
|
|
10
|
-
#
|
|
11
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
-
#
|
|
13
|
-
# Unless required by applicable law or agreed to in writing,
|
|
14
|
-
# software distributed under the License is distributed on an
|
|
15
|
-
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
16
|
-
# KIND, either express or implied. See the License for the
|
|
17
|
-
# specific language governing permissions and limitations
|
|
18
|
-
# under the License.
|
|
19
|
-
|
|
20
|
-
class Selenium::WebDriver::Remote::Bridge
|
|
21
|
-
|
|
22
|
-
#
|
|
23
|
-
# https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol#command-reference
|
|
24
|
-
#
|
|
25
|
-
|
|
26
|
-
command :newSession, :post, "session"
|
|
27
|
-
command :getCapabilities, :get, "session/:session_id"
|
|
28
|
-
command :status, :get, "status"
|
|
29
|
-
|
|
30
|
-
#
|
|
31
|
-
# basic driver
|
|
32
|
-
#
|
|
33
|
-
|
|
34
|
-
command :getCurrentUrl, :get, "session/:session_id/url"
|
|
35
|
-
command :get, :post, "session/:session_id/url"
|
|
36
|
-
command :goForward, :post, "session/:session_id/forward"
|
|
37
|
-
command :goBack, :post, "session/:session_id/back"
|
|
38
|
-
command :refresh, :post, "session/:session_id/refresh"
|
|
39
|
-
command :quit, :delete, "session/:session_id"
|
|
40
|
-
command :close, :delete, "session/:session_id/window"
|
|
41
|
-
command :getPageSource, :get, "session/:session_id/source"
|
|
42
|
-
command :getTitle, :get, "session/:session_id/title"
|
|
43
|
-
command :findElement, :post, "session/:session_id/element"
|
|
44
|
-
command :findElements, :post, "session/:session_id/elements"
|
|
45
|
-
command :getActiveElement, :post, "session/:session_id/element/active"
|
|
46
|
-
|
|
47
|
-
#
|
|
48
|
-
# window handling
|
|
49
|
-
#
|
|
50
|
-
|
|
51
|
-
command :getCurrentWindowHandle, :get, "session/:session_id/window_handle"
|
|
52
|
-
command :getWindowHandles, :get, "session/:session_id/window_handles"
|
|
53
|
-
command :setWindowSize, :post, "session/:session_id/window/:window_handle/size"
|
|
54
|
-
command :setWindowPosition, :post, "session/:session_id/window/:window_handle/position"
|
|
55
|
-
command :getWindowSize, :get, "session/:session_id/window/:window_handle/size"
|
|
56
|
-
command :getWindowPosition, :get, "session/:session_id/window/:window_handle/position"
|
|
57
|
-
command :maximizeWindow, :post, "session/:session_id/window/:window_handle/maximize"
|
|
58
|
-
|
|
59
|
-
#
|
|
60
|
-
# script execution
|
|
61
|
-
#
|
|
62
|
-
|
|
63
|
-
command :executeScript, :post, "session/:session_id/execute"
|
|
64
|
-
command :executeAsyncScript, :post, "session/:session_id/execute_async"
|
|
65
|
-
|
|
66
|
-
#
|
|
67
|
-
# screenshot
|
|
68
|
-
#
|
|
69
|
-
|
|
70
|
-
command :screenshot, :get, "session/:session_id/screenshot"
|
|
71
|
-
|
|
72
|
-
#
|
|
73
|
-
# alerts
|
|
74
|
-
#
|
|
75
|
-
|
|
76
|
-
command :dismissAlert, :post, "session/:session_id/dismiss_alert"
|
|
77
|
-
command :acceptAlert, :post, "session/:session_id/accept_alert"
|
|
78
|
-
command :getAlertText, :get, "session/:session_id/alert_text"
|
|
79
|
-
command :setAlertValue, :post, "session/:session_id/alert_text"
|
|
80
|
-
command :setAuthentication, :post, "session/:session_id/alert/credentials"
|
|
81
|
-
|
|
82
|
-
#
|
|
83
|
-
# target locator
|
|
84
|
-
#
|
|
85
|
-
|
|
86
|
-
command :switchToFrame, :post, "session/:session_id/frame"
|
|
87
|
-
command :switchToParentFrame, :post, "session/:session_id/frame/parent"
|
|
88
|
-
command :switchToWindow, :post, "session/:session_id/window"
|
|
89
|
-
|
|
90
|
-
#
|
|
91
|
-
# options
|
|
92
|
-
#
|
|
93
|
-
|
|
94
|
-
command :getCookies, :get, "session/:session_id/cookie"
|
|
95
|
-
command :addCookie, :post, "session/:session_id/cookie"
|
|
96
|
-
command :deleteAllCookies, :delete, "session/:session_id/cookie"
|
|
97
|
-
command :deleteCookie, :delete, "session/:session_id/cookie/:name"
|
|
98
|
-
|
|
99
|
-
#
|
|
100
|
-
# timeouts
|
|
101
|
-
#
|
|
102
|
-
|
|
103
|
-
command :implicitlyWait, :post, "session/:session_id/timeouts/implicit_wait"
|
|
104
|
-
command :setScriptTimeout, :post, "session/:session_id/timeouts/async_script"
|
|
105
|
-
command :setTimeout, :post, "session/:session_id/timeouts"
|
|
106
|
-
|
|
107
|
-
#
|
|
108
|
-
# element
|
|
109
|
-
#
|
|
110
|
-
|
|
111
|
-
command :describeElement, :get, "session/:session_id/element/:id"
|
|
112
|
-
command :findChildElement, :post, "session/:session_id/element/:id/element"
|
|
113
|
-
command :findChildElements, :post, "session/:session_id/element/:id/elements"
|
|
114
|
-
command :clickElement, :post, "session/:session_id/element/:id/click"
|
|
115
|
-
command :submitElement, :post, "session/:session_id/element/:id/submit"
|
|
116
|
-
command :getElementValue, :get, "session/:session_id/element/:id/value"
|
|
117
|
-
command :sendKeysToElement, :post, "session/:session_id/element/:id/value"
|
|
118
|
-
command :uploadFile, :post, "session/:session_id/file"
|
|
119
|
-
command :getElementTagName, :get, "session/:session_id/element/:id/name"
|
|
120
|
-
command :clearElement, :post, "session/:session_id/element/:id/clear"
|
|
121
|
-
command :isElementSelected, :get, "session/:session_id/element/:id/selected"
|
|
122
|
-
command :isElementEnabled, :get, "session/:session_id/element/:id/enabled"
|
|
123
|
-
command :getElementAttribute, :get, "session/:session_id/element/:id/attribute/:name"
|
|
124
|
-
command :elementEquals, :get, "session/:session_id/element/:id/equals/:other"
|
|
125
|
-
command :isElementDisplayed, :get, "session/:session_id/element/:id/displayed"
|
|
126
|
-
command :getElementLocation, :get, "session/:session_id/element/:id/location"
|
|
127
|
-
command :getElementLocationOnceScrolledIntoView, :get, "session/:session_id/element/:id/location_in_view"
|
|
128
|
-
command :getElementSize, :get, "session/:session_id/element/:id/size"
|
|
129
|
-
command :dragElement, :post, "session/:session_id/element/:id/drag"
|
|
130
|
-
command :getElementValueOfCssProperty, :get, "session/:session_id/element/:id/css/:property_name"
|
|
131
|
-
command :getElementText, :get, "session/:session_id/element/:id/text"
|
|
132
|
-
|
|
133
|
-
#
|
|
134
|
-
# rotatable
|
|
135
|
-
#
|
|
136
|
-
|
|
137
|
-
command :getScreenOrientation, :get, "session/:session_id/orientation"
|
|
138
|
-
command :setScreenOrientation, :post, "session/:session_id/orientation"
|
|
139
|
-
|
|
140
|
-
#
|
|
141
|
-
# interactions API
|
|
142
|
-
#
|
|
143
|
-
|
|
144
|
-
command :click, :post, "session/:session_id/click"
|
|
145
|
-
command :doubleClick, :post, "session/:session_id/doubleclick"
|
|
146
|
-
command :mouseDown, :post, "session/:session_id/buttondown"
|
|
147
|
-
command :mouseUp, :post, "session/:session_id/buttonup"
|
|
148
|
-
command :mouseMoveTo, :post, "session/:session_id/moveto"
|
|
149
|
-
command :sendModifierKeyToActiveElement, :post, "session/:session_id/modifier"
|
|
150
|
-
command :sendKeysToActiveElement, :post, "session/:session_id/keys"
|
|
151
|
-
|
|
152
|
-
#
|
|
153
|
-
# html 5
|
|
154
|
-
#
|
|
155
|
-
|
|
156
|
-
command :executeSql, :post, "session/:session_id/execute_sql"
|
|
157
|
-
|
|
158
|
-
command :getLocation, :get, "session/:session_id/location"
|
|
159
|
-
command :setLocation, :post, "session/:session_id/location"
|
|
160
|
-
|
|
161
|
-
command :getAppCache, :get, "session/:session_id/application_cache"
|
|
162
|
-
command :getAppCacheStatus, :get, "session/:session_id/application_cache/status"
|
|
163
|
-
command :clearAppCache, :delete, "session/:session_id/application_cache/clear"
|
|
164
|
-
|
|
165
|
-
command :getNetworkConnection, :get, "session/:session_id/network_connection"
|
|
166
|
-
command :setNetworkConnection, :post, "session/:session_id/network_connection"
|
|
167
|
-
|
|
168
|
-
command :getLocalStorageItem, :get, "session/:session_id/local_storage/key/:key"
|
|
169
|
-
command :removeLocalStorageItem, :delete, "session/:session_id/local_storage/key/:key"
|
|
170
|
-
command :getLocalStorageKeys, :get, "session/:session_id/local_storage"
|
|
171
|
-
command :setLocalStorageItem, :post, "session/:session_id/local_storage"
|
|
172
|
-
command :clearLocalStorage, :delete, "session/:session_id/local_storage"
|
|
173
|
-
command :getLocalStorageSize, :get, "session/:session_id/local_storage/size"
|
|
174
|
-
|
|
175
|
-
command :getSessionStorageItem, :get, "session/:session_id/session_storage/key/:key"
|
|
176
|
-
command :removeSessionStorageItem, :delete, "session/:session_id/session_storage/key/:key"
|
|
177
|
-
command :getSessionStorageKeys, :get, "session/:session_id/session_storage"
|
|
178
|
-
command :setSessionStorageItem, :post, "session/:session_id/session_storage"
|
|
179
|
-
command :clearSessionStorage, :delete, "session/:session_id/session_storage"
|
|
180
|
-
command :getSessionStorageSize, :get, "session/:session_id/session_storage/size"
|
|
181
|
-
|
|
182
|
-
#
|
|
183
|
-
# ime
|
|
184
|
-
#
|
|
185
|
-
|
|
186
|
-
command :imeGetAvailableEngines, :get, "session/:session_id/ime/available_engines"
|
|
187
|
-
command :imeGetActiveEngine, :get, "session/:session_id/ime/active_engine"
|
|
188
|
-
command :imeIsActivated, :get, "session/:session_id/ime/activated"
|
|
189
|
-
command :imeDeactivate, :post, "session/:session_id/ime/deactivate"
|
|
190
|
-
command :imeActivateEngine, :post, "session/:session_id/ime/activate"
|
|
191
|
-
|
|
192
|
-
#
|
|
193
|
-
# touch
|
|
194
|
-
#
|
|
195
|
-
|
|
196
|
-
command :touchSingleTap, :post, "session/:session_id/touch/click"
|
|
197
|
-
command :touchDoubleTap, :post, "session/:session_id/touch/doubleclick"
|
|
198
|
-
command :touchLongPress, :post, "session/:session_id/touch/longclick"
|
|
199
|
-
command :touchDown, :post, "session/:session_id/touch/down"
|
|
200
|
-
command :touchUp, :post, "session/:session_id/touch/up"
|
|
201
|
-
command :touchMove, :post, "session/:session_id/touch/move"
|
|
202
|
-
command :touchScroll, :post, "session/:session_id/touch/scroll"
|
|
203
|
-
command :touchFlick, :post, "session/:session_id/touch/flick"
|
|
204
|
-
|
|
205
|
-
#
|
|
206
|
-
# logs
|
|
207
|
-
#
|
|
208
|
-
|
|
209
|
-
command :getAvailableLogTypes, :get, "session/:session_id/log/types"
|
|
210
|
-
command :getLog, :post, "session/:session_id/log"
|
|
211
|
-
end
|
|
@@ -1,668 +0,0 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
#
|
|
3
|
-
# Licensed to the Software Freedom Conservancy (SFC) under one
|
|
4
|
-
# or more contributor license agreements. See the NOTICE file
|
|
5
|
-
# distributed with this work for additional information
|
|
6
|
-
# regarding copyright ownership. The SFC licenses this file
|
|
7
|
-
# to you under the Apache License, Version 2.0 (the
|
|
8
|
-
# "License"); you may not use this file except in compliance
|
|
9
|
-
# with the License. You may obtain a copy of the License at
|
|
10
|
-
#
|
|
11
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
-
#
|
|
13
|
-
# Unless required by applicable law or agreed to in writing,
|
|
14
|
-
# software distributed under the License is distributed on an
|
|
15
|
-
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
16
|
-
# KIND, either express or implied. See the License for the
|
|
17
|
-
# specific language governing permissions and limitations
|
|
18
|
-
# under the License.
|
|
19
|
-
|
|
20
|
-
require 'json'
|
|
21
|
-
|
|
22
|
-
module Selenium
|
|
23
|
-
module WebDriver
|
|
24
|
-
module Remote
|
|
25
|
-
|
|
26
|
-
#
|
|
27
|
-
# Low level bridge to the remote server, through which the rest of the API works.
|
|
28
|
-
#
|
|
29
|
-
# @api private
|
|
30
|
-
#
|
|
31
|
-
|
|
32
|
-
class W3CBridge
|
|
33
|
-
include BridgeHelper
|
|
34
|
-
|
|
35
|
-
COMMANDS = {}
|
|
36
|
-
|
|
37
|
-
#
|
|
38
|
-
# Defines a wrapper method for a command, which ultimately calls #execute.
|
|
39
|
-
#
|
|
40
|
-
# @param name [Symbol]
|
|
41
|
-
# name of the resulting method
|
|
42
|
-
# @param verb [Symbol]
|
|
43
|
-
# the appropriate http verb, such as :get, :post, or :delete
|
|
44
|
-
# @param url [String]
|
|
45
|
-
# a URL template, which can include some arguments, much like the definitions on the server.
|
|
46
|
-
# the :session_id parameter is implicitly handled, but the remainder will become required method arguments.
|
|
47
|
-
#
|
|
48
|
-
|
|
49
|
-
def self.command(name, verb, url)
|
|
50
|
-
COMMANDS[name] = [verb, url.freeze]
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
attr_accessor :context, :http, :file_detector
|
|
54
|
-
attr_reader :capabilities
|
|
55
|
-
|
|
56
|
-
#
|
|
57
|
-
# Initializes the bridge with the given server URL.
|
|
58
|
-
#
|
|
59
|
-
# @param url [String] url for the remote server
|
|
60
|
-
# @param http_client [Object] an HTTP client instance that implements the same protocol as Http::Default
|
|
61
|
-
# @param desired_capabilities [Capabilities] an instance of Remote::Capabilities describing the capabilities you want
|
|
62
|
-
#
|
|
63
|
-
|
|
64
|
-
def initialize(opts = {})
|
|
65
|
-
if opts.fetch(:desired_capabilities, {})[:browser_name] == 'MicrosoftEdge'
|
|
66
|
-
require_relative '../edge/legacy_support'
|
|
67
|
-
extend Edge::LegacySupport
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
opts = opts.dup
|
|
71
|
-
|
|
72
|
-
http_client = opts.delete(:http_client) { Http::Default.new }
|
|
73
|
-
desired_capabilities = opts.delete(:desired_capabilities) { W3CCapabilities.firefox }
|
|
74
|
-
url = opts.delete(:url) { "http://#{Platform.localhost}:4444/wd/hub" }
|
|
75
|
-
|
|
76
|
-
desired_capabilities = W3CCapabilities.send(desired_capabilities) if desired_capabilities.is_a? Symbol
|
|
77
|
-
|
|
78
|
-
desired_capabilities[:marionette] = opts.delete(:marionette) unless opts[:marionette].nil?
|
|
79
|
-
|
|
80
|
-
unless opts.empty?
|
|
81
|
-
raise ArgumentError, "unknown option#{'s' if opts.size != 1}: #{opts.inspect}"
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
uri = url.kind_of?(URI) ? url : URI.parse(url)
|
|
85
|
-
uri.path += "/" unless uri.path =~ /\/$/
|
|
86
|
-
|
|
87
|
-
http_client.server_url = uri
|
|
88
|
-
|
|
89
|
-
@http = http_client
|
|
90
|
-
@capabilities = create_session(desired_capabilities)
|
|
91
|
-
@file_detector = nil
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
def browser
|
|
95
|
-
@browser ||= (
|
|
96
|
-
name = @capabilities.browser_name
|
|
97
|
-
name ? name.gsub(" ", "_").to_sym : 'unknown'
|
|
98
|
-
)
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
def driver_extensions
|
|
102
|
-
[
|
|
103
|
-
DriverExtensions::HasInputDevices,
|
|
104
|
-
DriverExtensions::UploadsFiles,
|
|
105
|
-
DriverExtensions::TakesScreenshot,
|
|
106
|
-
DriverExtensions::HasSessionId,
|
|
107
|
-
DriverExtensions::Rotatable,
|
|
108
|
-
DriverExtensions::HasTouchScreen,
|
|
109
|
-
DriverExtensions::HasRemoteStatus,
|
|
110
|
-
DriverExtensions::HasWebStorage
|
|
111
|
-
]
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
#
|
|
115
|
-
# Returns the current session ID.
|
|
116
|
-
#
|
|
117
|
-
|
|
118
|
-
def session_id
|
|
119
|
-
@session_id || raise(Error::WebDriverError, "no current session exists")
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
def create_session(desired_capabilities)
|
|
123
|
-
resp = raw_execute :newSession, {}, :desiredCapabilities => desired_capabilities
|
|
124
|
-
@session_id = resp['sessionId'] or raise Error::WebDriverError, 'no sessionId in returned payload'
|
|
125
|
-
|
|
126
|
-
W3CCapabilities.json_create resp['value']
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
def status
|
|
130
|
-
jwp = Selenium::WebDriver::Remote::Bridge::COMMANDS[:status]
|
|
131
|
-
self.class.command(:status, jwp.first, jwp.last)
|
|
132
|
-
execute :status
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
def get(url)
|
|
136
|
-
execute :get, {}, :url => url
|
|
137
|
-
end
|
|
138
|
-
|
|
139
|
-
def setImplicitWaitTimeout(milliseconds)
|
|
140
|
-
setTimeout('implicit', milliseconds)
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
def setScriptTimeout(milliseconds)
|
|
144
|
-
setTimeout('script', milliseconds)
|
|
145
|
-
end
|
|
146
|
-
|
|
147
|
-
def setTimeout(type, milliseconds)
|
|
148
|
-
execute :setTimeout, {}, :type => type, :ms => milliseconds
|
|
149
|
-
end
|
|
150
|
-
|
|
151
|
-
#
|
|
152
|
-
# alerts
|
|
153
|
-
#
|
|
154
|
-
|
|
155
|
-
def acceptAlert
|
|
156
|
-
execute :acceptAlert
|
|
157
|
-
end
|
|
158
|
-
|
|
159
|
-
def dismissAlert
|
|
160
|
-
execute :dismissAlert
|
|
161
|
-
end
|
|
162
|
-
|
|
163
|
-
def setAlertValue(keys)
|
|
164
|
-
execute :sendAlertText, {}, {:handler => 'prompt', :message => keys}
|
|
165
|
-
end
|
|
166
|
-
|
|
167
|
-
def getAlertText
|
|
168
|
-
execute :getAlertText
|
|
169
|
-
end
|
|
170
|
-
|
|
171
|
-
#
|
|
172
|
-
# navigation
|
|
173
|
-
#
|
|
174
|
-
|
|
175
|
-
def goBack
|
|
176
|
-
execute :back
|
|
177
|
-
end
|
|
178
|
-
|
|
179
|
-
def goForward
|
|
180
|
-
execute :forward
|
|
181
|
-
end
|
|
182
|
-
|
|
183
|
-
def getCurrentUrl
|
|
184
|
-
execute :getCurrentUrl
|
|
185
|
-
end
|
|
186
|
-
|
|
187
|
-
def getTitle
|
|
188
|
-
execute :getTitle
|
|
189
|
-
end
|
|
190
|
-
|
|
191
|
-
def getPageSource
|
|
192
|
-
executeScript("var source = document.documentElement.outerHTML;" +
|
|
193
|
-
"if (!source) { source = new XMLSerializer().serializeToString(document); }" +
|
|
194
|
-
"return source;")
|
|
195
|
-
end
|
|
196
|
-
|
|
197
|
-
def switchToWindow(name)
|
|
198
|
-
execute :switchToWindow, {}, :handle => name
|
|
199
|
-
end
|
|
200
|
-
|
|
201
|
-
def switchToFrame(id)
|
|
202
|
-
id = find_element_by('id', id) if id.is_a? String
|
|
203
|
-
execute :switchToFrame, {}, :id => id
|
|
204
|
-
end
|
|
205
|
-
|
|
206
|
-
def switchToParentFrame
|
|
207
|
-
execute :switchToParentFrame
|
|
208
|
-
end
|
|
209
|
-
|
|
210
|
-
def switchToDefaultContent
|
|
211
|
-
switchToFrame nil
|
|
212
|
-
end
|
|
213
|
-
|
|
214
|
-
QUIT_ERRORS = [IOError]
|
|
215
|
-
|
|
216
|
-
def quit
|
|
217
|
-
execute :deleteSession
|
|
218
|
-
http.close
|
|
219
|
-
rescue *QUIT_ERRORS
|
|
220
|
-
end
|
|
221
|
-
|
|
222
|
-
def close
|
|
223
|
-
execute :closeWindow
|
|
224
|
-
end
|
|
225
|
-
|
|
226
|
-
def refresh
|
|
227
|
-
execute :refresh
|
|
228
|
-
end
|
|
229
|
-
|
|
230
|
-
#
|
|
231
|
-
# window handling
|
|
232
|
-
#
|
|
233
|
-
|
|
234
|
-
def getWindowHandles
|
|
235
|
-
execute :getWindowHandles
|
|
236
|
-
end
|
|
237
|
-
|
|
238
|
-
def getCurrentWindowHandle
|
|
239
|
-
execute :getWindowHandle
|
|
240
|
-
end
|
|
241
|
-
|
|
242
|
-
def setWindowSize(width, height, handle = :current)
|
|
243
|
-
unless handle == :current
|
|
244
|
-
raise Error::WebDriverError, 'Switch to desired window before changing its size'
|
|
245
|
-
end
|
|
246
|
-
execute :setWindowSize, {}, {:width => width,
|
|
247
|
-
:height => height}
|
|
248
|
-
end
|
|
249
|
-
|
|
250
|
-
def maximizeWindow(handle = :current)
|
|
251
|
-
unless handle == :current
|
|
252
|
-
raise Error::UnsupportedOperationError, 'Switch to desired window before changing its size'
|
|
253
|
-
end
|
|
254
|
-
execute :maximizeWindow
|
|
255
|
-
end
|
|
256
|
-
|
|
257
|
-
def fullscreenWindow
|
|
258
|
-
execute :fullscreenWindow
|
|
259
|
-
end
|
|
260
|
-
|
|
261
|
-
def getWindowSize(handle = :current)
|
|
262
|
-
unless handle == :current
|
|
263
|
-
raise Error::UnsupportedOperationError, 'Switch to desired window before getting its size'
|
|
264
|
-
end
|
|
265
|
-
data = execute :getWindowSize
|
|
266
|
-
|
|
267
|
-
Dimension.new data['width'], data['height']
|
|
268
|
-
end
|
|
269
|
-
|
|
270
|
-
def setWindowPosition(_x, _y, _handle = nil)
|
|
271
|
-
raise Error::UnsupportedOperationError, 'The W3C standard does not currently support setting the Window Position'
|
|
272
|
-
end
|
|
273
|
-
|
|
274
|
-
def getWindowPosition(_handle = nil)
|
|
275
|
-
raise Error::UnsupportedOperationError, 'The W3C standard does not currently support getting the Window Position'
|
|
276
|
-
end
|
|
277
|
-
|
|
278
|
-
def getScreenshot
|
|
279
|
-
execute :takeScreenshot
|
|
280
|
-
end
|
|
281
|
-
|
|
282
|
-
#
|
|
283
|
-
# HTML 5
|
|
284
|
-
#
|
|
285
|
-
|
|
286
|
-
def getLocalStorageItem(key)
|
|
287
|
-
executeScript("return localStorage.getItem('#{key}')")
|
|
288
|
-
end
|
|
289
|
-
|
|
290
|
-
def removeLocalStorageItem(key)
|
|
291
|
-
executeScript("localStorage.removeItem('#{key}')")
|
|
292
|
-
end
|
|
293
|
-
|
|
294
|
-
def getLocalStorageKeys
|
|
295
|
-
executeScript("return Object.keys(localStorage)")
|
|
296
|
-
end
|
|
297
|
-
|
|
298
|
-
def setLocalStorageItem(key, value)
|
|
299
|
-
executeScript("localStorage.setItem('#{key}', '#{value}')")
|
|
300
|
-
end
|
|
301
|
-
|
|
302
|
-
def clearLocalStorage
|
|
303
|
-
executeScript("localStorage.clear()")
|
|
304
|
-
end
|
|
305
|
-
|
|
306
|
-
def getLocalStorageSize
|
|
307
|
-
executeScript("return localStorage.length")
|
|
308
|
-
end
|
|
309
|
-
|
|
310
|
-
def getSessionStorageItem(key)
|
|
311
|
-
executeScript("return sessionStorage.getItem('#{key}')")
|
|
312
|
-
end
|
|
313
|
-
|
|
314
|
-
def removeSessionStorageItem(key)
|
|
315
|
-
executeScript("sessionStorage.removeItem('#{key}')")
|
|
316
|
-
end
|
|
317
|
-
|
|
318
|
-
def getSessionStorageKeys
|
|
319
|
-
executeScript("return Object.keys(sessionStorage)")
|
|
320
|
-
end
|
|
321
|
-
|
|
322
|
-
def setSessionStorageItem(key, value)
|
|
323
|
-
executeScript("sessionStorage.setItem('#{key}', '#{value}')")
|
|
324
|
-
end
|
|
325
|
-
|
|
326
|
-
def clearSessionStorage
|
|
327
|
-
executeScript("sessionStorage.clear()")
|
|
328
|
-
end
|
|
329
|
-
|
|
330
|
-
def getSessionStorageSize
|
|
331
|
-
executeScript("return sessionStorage.length")
|
|
332
|
-
end
|
|
333
|
-
|
|
334
|
-
def getLocation
|
|
335
|
-
raise Error::UnsupportedOperationError, 'The W3C standard does not currently support getting location'
|
|
336
|
-
end
|
|
337
|
-
|
|
338
|
-
def setLocation(_lat, _lon, _alt)
|
|
339
|
-
raise Error::UnsupportedOperationError, 'The W3C standard does not currently support setting location'
|
|
340
|
-
end
|
|
341
|
-
|
|
342
|
-
def getNetworkConnection
|
|
343
|
-
raise Error::UnsupportedOperationError, 'The W3C standard does not currently support getting network connection'
|
|
344
|
-
end
|
|
345
|
-
|
|
346
|
-
def setNetworkConnection(_type)
|
|
347
|
-
raise Error::UnsupportedOperationError, 'The W3C standard does not currently support setting network connection'
|
|
348
|
-
end
|
|
349
|
-
|
|
350
|
-
#
|
|
351
|
-
# javascript execution
|
|
352
|
-
#
|
|
353
|
-
|
|
354
|
-
def executeScript(script, *args)
|
|
355
|
-
result = execute :executeScript, {}, :script => script, :args => args
|
|
356
|
-
unwrap_script_result result
|
|
357
|
-
end
|
|
358
|
-
|
|
359
|
-
def executeAsyncScript(script, *args)
|
|
360
|
-
result = execute :executeAsyncScript, {}, :script => script, :args => args
|
|
361
|
-
unwrap_script_result result
|
|
362
|
-
end
|
|
363
|
-
|
|
364
|
-
#
|
|
365
|
-
# cookies
|
|
366
|
-
#
|
|
367
|
-
|
|
368
|
-
def addCookie(cookie)
|
|
369
|
-
execute :addCookie, {}, :cookie => cookie
|
|
370
|
-
end
|
|
371
|
-
|
|
372
|
-
def deleteCookie(name)
|
|
373
|
-
execute :deleteCookie, :name => name
|
|
374
|
-
end
|
|
375
|
-
|
|
376
|
-
# TODO - write specs
|
|
377
|
-
def getCookie(name)
|
|
378
|
-
execute :getCookie, :name => name
|
|
379
|
-
end
|
|
380
|
-
|
|
381
|
-
def getAllCookies
|
|
382
|
-
execute :getAllCookies
|
|
383
|
-
end
|
|
384
|
-
|
|
385
|
-
def deleteAllCookies
|
|
386
|
-
getAllCookies.each { |cookie| deleteCookie(cookie['name'])}
|
|
387
|
-
end
|
|
388
|
-
|
|
389
|
-
#
|
|
390
|
-
# actions
|
|
391
|
-
#
|
|
392
|
-
|
|
393
|
-
def clickElement(element)
|
|
394
|
-
execute :elementClick, :id => element
|
|
395
|
-
end
|
|
396
|
-
|
|
397
|
-
def click
|
|
398
|
-
execute :click, {}, :button => 0
|
|
399
|
-
end
|
|
400
|
-
|
|
401
|
-
def doubleClick
|
|
402
|
-
execute :doubleClick
|
|
403
|
-
end
|
|
404
|
-
|
|
405
|
-
def contextClick
|
|
406
|
-
execute :click, {}, :button => 2
|
|
407
|
-
end
|
|
408
|
-
|
|
409
|
-
def mouseDown
|
|
410
|
-
execute :mouseDown
|
|
411
|
-
end
|
|
412
|
-
|
|
413
|
-
def mouseUp
|
|
414
|
-
execute :mouseUp
|
|
415
|
-
end
|
|
416
|
-
|
|
417
|
-
def mouseMoveTo(element, x = nil, y = nil)
|
|
418
|
-
params = { :element => element }
|
|
419
|
-
|
|
420
|
-
if x && y
|
|
421
|
-
params.merge! :xoffset => x, :yoffset => y
|
|
422
|
-
end
|
|
423
|
-
|
|
424
|
-
execute :mouseMoveTo, {}, params
|
|
425
|
-
end
|
|
426
|
-
|
|
427
|
-
def sendKeysToActiveElement(keys)
|
|
428
|
-
sendKeysToElement(getActiveElement, keys)
|
|
429
|
-
end
|
|
430
|
-
|
|
431
|
-
# TODO - Implement file verification
|
|
432
|
-
def sendKeysToElement(element, keys)
|
|
433
|
-
execute :elementSendKeys, {:id => element}, {:value => keys.join('').split(//)}
|
|
434
|
-
end
|
|
435
|
-
|
|
436
|
-
def clearElement(element)
|
|
437
|
-
execute :elementClear, :id => element
|
|
438
|
-
end
|
|
439
|
-
|
|
440
|
-
def submitElement(element)
|
|
441
|
-
executeScript("var e = arguments[0].ownerDocument.createEvent('Event');" +
|
|
442
|
-
"e.initEvent('submit', true, true);" +
|
|
443
|
-
"if (arguments[0].dispatchEvent(e)) { arguments[0].submit() }", element)
|
|
444
|
-
end
|
|
445
|
-
|
|
446
|
-
def dragElement(element, right_by, down_by)
|
|
447
|
-
execute :dragElement, {:id => element}, :x => right_by, :y => down_by
|
|
448
|
-
end
|
|
449
|
-
|
|
450
|
-
def touchSingleTap(element)
|
|
451
|
-
execute :touchSingleTap, {}, :element => element
|
|
452
|
-
end
|
|
453
|
-
|
|
454
|
-
def touchDoubleTap(element)
|
|
455
|
-
execute :touchDoubleTap, {}, :element => element
|
|
456
|
-
end
|
|
457
|
-
|
|
458
|
-
def touchLongPress(element)
|
|
459
|
-
execute :touchLongPress, {}, :element => element
|
|
460
|
-
end
|
|
461
|
-
|
|
462
|
-
def touchDown(x, y)
|
|
463
|
-
execute :touchDown, {}, :x => x, :y => y
|
|
464
|
-
end
|
|
465
|
-
|
|
466
|
-
def touchUp(x, y)
|
|
467
|
-
execute :touchUp, {}, :x => x, :y => y
|
|
468
|
-
end
|
|
469
|
-
|
|
470
|
-
def touchMove(x, y)
|
|
471
|
-
execute :touchMove, {}, :x => x, :y => y
|
|
472
|
-
end
|
|
473
|
-
|
|
474
|
-
def touchScroll(element, x, y)
|
|
475
|
-
if element
|
|
476
|
-
execute :touchScroll, {}, :element => element,
|
|
477
|
-
:xoffset => x,
|
|
478
|
-
:yoffset => y
|
|
479
|
-
else
|
|
480
|
-
execute :touchScroll, {}, :xoffset => x, :yoffset => y
|
|
481
|
-
end
|
|
482
|
-
end
|
|
483
|
-
|
|
484
|
-
def touchFlick(xspeed, yspeed)
|
|
485
|
-
execute :touchFlick, {}, :xspeed => xspeed, :yspeed => yspeed
|
|
486
|
-
end
|
|
487
|
-
|
|
488
|
-
def touchElementFlick(element, right_by, down_by, speed)
|
|
489
|
-
execute :touchFlick, {}, :element => element,
|
|
490
|
-
:xoffset => right_by,
|
|
491
|
-
:yoffset => down_by,
|
|
492
|
-
:speed => speed
|
|
493
|
-
|
|
494
|
-
end
|
|
495
|
-
|
|
496
|
-
def setScreenOrientation(orientation)
|
|
497
|
-
execute :setScreenOrientation, {}, :orientation => orientation
|
|
498
|
-
end
|
|
499
|
-
|
|
500
|
-
def getScreenOrientation
|
|
501
|
-
execute :getScreenOrientation
|
|
502
|
-
end
|
|
503
|
-
|
|
504
|
-
#
|
|
505
|
-
# element properties
|
|
506
|
-
#
|
|
507
|
-
|
|
508
|
-
def getElementTagName(element)
|
|
509
|
-
execute :getElementTagName, :id => element
|
|
510
|
-
end
|
|
511
|
-
|
|
512
|
-
def getElementAttribute(element, name)
|
|
513
|
-
execute :getElementAttribute, :id => element, :name => name
|
|
514
|
-
end
|
|
515
|
-
|
|
516
|
-
def getElementValue(element)
|
|
517
|
-
execute :getElementProperty, :id => element, :name => 'value'
|
|
518
|
-
end
|
|
519
|
-
|
|
520
|
-
def getElementText(element)
|
|
521
|
-
execute :getElementText, :id => element
|
|
522
|
-
end
|
|
523
|
-
|
|
524
|
-
def getElementLocation(element)
|
|
525
|
-
data = execute :getElementRect, :id => element
|
|
526
|
-
|
|
527
|
-
Point.new data['x'], data['y']
|
|
528
|
-
end
|
|
529
|
-
|
|
530
|
-
def getElementLocationOnceScrolledIntoView(element)
|
|
531
|
-
sendKeysToElement(element, [''])
|
|
532
|
-
getElementLocation(element)
|
|
533
|
-
end
|
|
534
|
-
|
|
535
|
-
def getElementSize(element)
|
|
536
|
-
data = execute :getElementRect, :id => element
|
|
537
|
-
|
|
538
|
-
Dimension.new data['width'], data['height']
|
|
539
|
-
end
|
|
540
|
-
|
|
541
|
-
def isElementEnabled(element)
|
|
542
|
-
execute :isElementEnabled, :id => element
|
|
543
|
-
end
|
|
544
|
-
|
|
545
|
-
def isElementSelected(element)
|
|
546
|
-
execute :isElementSelected, :id => element
|
|
547
|
-
end
|
|
548
|
-
|
|
549
|
-
def isElementDisplayed(element)
|
|
550
|
-
jwp = Selenium::WebDriver::Remote::Bridge::COMMANDS[:isElementDisplayed]
|
|
551
|
-
self.class.command(:isElementDisplayed, jwp.first, jwp.last)
|
|
552
|
-
execute :isElementDisplayed, :id => element
|
|
553
|
-
end
|
|
554
|
-
|
|
555
|
-
def getElementValueOfCssProperty(element, prop)
|
|
556
|
-
execute :getElementCssValue, :id => element, :property_name => prop
|
|
557
|
-
end
|
|
558
|
-
|
|
559
|
-
#
|
|
560
|
-
# finding elements
|
|
561
|
-
#
|
|
562
|
-
|
|
563
|
-
def getActiveElement
|
|
564
|
-
Element.new self, element_id_from(execute(:getActiveElement))
|
|
565
|
-
end
|
|
566
|
-
alias_method :switchToActiveElement, :getActiveElement
|
|
567
|
-
|
|
568
|
-
def find_element_by(how, what, parent = nil)
|
|
569
|
-
how, what = convert_locators(how, what)
|
|
570
|
-
|
|
571
|
-
if parent
|
|
572
|
-
id = execute :findChildElement, {:id => parent}, {:using => how, :value => what}
|
|
573
|
-
else
|
|
574
|
-
id = execute :findElement, {}, {:using => how, :value => what}
|
|
575
|
-
end
|
|
576
|
-
|
|
577
|
-
Element.new self, element_id_from(id)
|
|
578
|
-
end
|
|
579
|
-
|
|
580
|
-
def find_elements_by(how, what, parent = nil)
|
|
581
|
-
how, what = convert_locators(how, what)
|
|
582
|
-
|
|
583
|
-
if parent
|
|
584
|
-
ids = execute :findChildElements, {:id => parent}, {:using => how, :value => what}
|
|
585
|
-
else
|
|
586
|
-
ids = execute :findElements, {}, {:using => how, :value => what}
|
|
587
|
-
end
|
|
588
|
-
|
|
589
|
-
ids.map { |id| Element.new self, element_id_from(id) }
|
|
590
|
-
end
|
|
591
|
-
|
|
592
|
-
private
|
|
593
|
-
|
|
594
|
-
def convert_locators(how, what)
|
|
595
|
-
case how
|
|
596
|
-
when 'class name'
|
|
597
|
-
how = 'css selector'
|
|
598
|
-
what = ".#{escape_css(what)}"
|
|
599
|
-
when 'id'
|
|
600
|
-
how = 'css selector'
|
|
601
|
-
what = "##{escape_css(what)}"
|
|
602
|
-
when 'name'
|
|
603
|
-
how = 'css selector'
|
|
604
|
-
what = "*[name='#{escape_css(what)}']"
|
|
605
|
-
when 'tag name'
|
|
606
|
-
how = 'css selector'
|
|
607
|
-
end
|
|
608
|
-
return how, what
|
|
609
|
-
end
|
|
610
|
-
|
|
611
|
-
#
|
|
612
|
-
# executes a command on the remote server.
|
|
613
|
-
#
|
|
614
|
-
#
|
|
615
|
-
# Returns the 'value' of the returned payload
|
|
616
|
-
#
|
|
617
|
-
|
|
618
|
-
def execute(*args)
|
|
619
|
-
result = raw_execute(*args)
|
|
620
|
-
result.payload.key?('value') ? result['value'] : result
|
|
621
|
-
end
|
|
622
|
-
|
|
623
|
-
#
|
|
624
|
-
# executes a command on the remote server.
|
|
625
|
-
#
|
|
626
|
-
# @return [WebDriver::Remote::Response]
|
|
627
|
-
#
|
|
628
|
-
|
|
629
|
-
def raw_execute(command, opts = {}, command_hash = nil)
|
|
630
|
-
verb, path = COMMANDS[command] || raise(ArgumentError, "unknown command: #{command.inspect}")
|
|
631
|
-
path = path.dup
|
|
632
|
-
|
|
633
|
-
path[':session_id'] = @session_id if path.include?(":session_id")
|
|
634
|
-
|
|
635
|
-
begin
|
|
636
|
-
opts.each { |key, value|
|
|
637
|
-
path[key.inspect] = escaper.escape(value.to_s)
|
|
638
|
-
}
|
|
639
|
-
rescue IndexError
|
|
640
|
-
raise ArgumentError, "#{opts.inspect} invalid for #{command.inspect}"
|
|
641
|
-
end
|
|
642
|
-
|
|
643
|
-
puts "-> #{verb.to_s.upcase} #{path}" if $DEBUG
|
|
644
|
-
http.call verb, path, command_hash
|
|
645
|
-
end
|
|
646
|
-
|
|
647
|
-
def escaper
|
|
648
|
-
@escaper ||= defined?(URI::Parser) ? URI::Parser.new : URI
|
|
649
|
-
end
|
|
650
|
-
|
|
651
|
-
ESCAPE_CSS_REGEXP = /(['"\\#.:;,!?+<>=~*^$|%&@`{}\-\[\]\(\)])/
|
|
652
|
-
UNICODE_CODE_POINT = 30
|
|
653
|
-
|
|
654
|
-
# Escapes invalid characters in CSS selector.
|
|
655
|
-
# @see https://mathiasbynens.be/notes/css-escapes
|
|
656
|
-
def escape_css(string)
|
|
657
|
-
string = string.gsub(ESCAPE_CSS_REGEXP) { |match| "\\#{match}" }
|
|
658
|
-
if !string.empty? && string[0] =~ /[[:digit:]]/
|
|
659
|
-
string = "\\#{UNICODE_CODE_POINT + Integer(string[0])} #{string[1..-1]}"
|
|
660
|
-
end
|
|
661
|
-
|
|
662
|
-
string
|
|
663
|
-
end
|
|
664
|
-
|
|
665
|
-
end # W3CBridge
|
|
666
|
-
end # Remote
|
|
667
|
-
end # WebDriver
|
|
668
|
-
end # Selenium
|