selenium-webdriver 2.45.0 → 3.142.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (172) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGES +795 -3
  3. data/Gemfile +2 -0
  4. data/{COPYING → LICENSE} +1 -3
  5. data/README.md +13 -9
  6. data/lib/selenium/server.rb +93 -71
  7. data/lib/selenium/webdriver/atoms/getAttribute.js +7 -0
  8. data/lib/selenium/webdriver/atoms/isDisplayed.js +102 -0
  9. data/lib/selenium/webdriver/atoms.rb +37 -0
  10. data/lib/selenium/webdriver/chrome/bridge.rb +47 -99
  11. data/lib/selenium/webdriver/chrome/driver.rb +127 -0
  12. data/lib/selenium/webdriver/chrome/options.rb +190 -0
  13. data/lib/selenium/webdriver/chrome/profile.rb +40 -20
  14. data/lib/selenium/webdriver/chrome/service.rb +46 -62
  15. data/lib/selenium/webdriver/chrome.rb +34 -6
  16. data/lib/selenium/webdriver/common/action_builder.rb +69 -56
  17. data/lib/selenium/webdriver/common/alert.rb +25 -8
  18. data/lib/selenium/webdriver/common/bridge_helper.rb +35 -20
  19. data/lib/selenium/webdriver/common/driver.rb +90 -63
  20. data/lib/selenium/webdriver/common/driver_extensions/downloads_files.rb +45 -0
  21. data/lib/selenium/webdriver/common/driver_extensions/has_addons.rb +50 -0
  22. data/lib/selenium/webdriver/common/driver_extensions/has_debugger.rb +42 -0
  23. data/lib/selenium/webdriver/common/driver_extensions/has_location.rb +26 -11
  24. data/lib/selenium/webdriver/common/driver_extensions/has_network_conditions.rb +51 -0
  25. data/lib/selenium/webdriver/common/driver_extensions/has_network_connection.rb +58 -0
  26. data/lib/selenium/webdriver/common/driver_extensions/has_permissions.rb +51 -0
  27. data/lib/selenium/webdriver/common/driver_extensions/has_remote_status.rb +23 -6
  28. data/lib/selenium/webdriver/common/driver_extensions/has_session_id.rb +19 -2
  29. data/lib/selenium/webdriver/common/driver_extensions/has_touch_screen.rb +24 -7
  30. data/lib/selenium/webdriver/common/driver_extensions/has_web_storage.rb +19 -3
  31. data/lib/selenium/webdriver/common/driver_extensions/rotatable.rb +23 -7
  32. data/lib/selenium/webdriver/common/driver_extensions/takes_screenshot.rb +26 -5
  33. data/lib/selenium/webdriver/common/driver_extensions/uploads_files.rb +20 -6
  34. data/lib/selenium/webdriver/common/element.rb +79 -37
  35. data/lib/selenium/webdriver/common/error.rb +282 -106
  36. data/lib/selenium/webdriver/common/file_reaper.rb +23 -12
  37. data/lib/selenium/webdriver/common/html5/local_storage.rb +29 -12
  38. data/lib/selenium/webdriver/common/html5/session_storage.rb +29 -12
  39. data/lib/selenium/webdriver/common/html5/shared_web_storage.rb +29 -18
  40. data/lib/selenium/webdriver/common/interactions/input_device.rb +54 -0
  41. data/lib/selenium/webdriver/common/interactions/interaction.rb +53 -0
  42. data/lib/selenium/webdriver/common/interactions/interactions.rb +43 -0
  43. data/lib/selenium/webdriver/common/interactions/key_actions.rb +145 -0
  44. data/lib/selenium/webdriver/common/interactions/key_input.rb +66 -0
  45. data/lib/selenium/webdriver/common/interactions/none_input.rb +36 -0
  46. data/lib/selenium/webdriver/common/interactions/pointer_actions.rb +363 -0
  47. data/lib/selenium/webdriver/common/interactions/pointer_input.rb +139 -0
  48. data/lib/selenium/webdriver/common/keyboard.rb +27 -12
  49. data/lib/selenium/webdriver/common/keys.rb +118 -81
  50. data/lib/selenium/webdriver/common/log_entry.rb +27 -8
  51. data/lib/selenium/webdriver/common/logger.rb +115 -0
  52. data/lib/selenium/webdriver/common/logs.rb +24 -7
  53. data/lib/selenium/webdriver/common/manager.rb +177 -0
  54. data/lib/selenium/webdriver/common/mouse.rb +29 -12
  55. data/lib/selenium/webdriver/common/navigation.rb +21 -4
  56. data/lib/selenium/webdriver/common/options.rb +43 -126
  57. data/lib/selenium/webdriver/common/platform.rb +101 -97
  58. data/lib/selenium/webdriver/common/port_prober.rb +24 -17
  59. data/lib/selenium/webdriver/common/profile_helper.rb +27 -11
  60. data/lib/selenium/webdriver/common/proxy.rb +86 -73
  61. data/lib/selenium/webdriver/common/search_context.rb +49 -33
  62. data/lib/selenium/webdriver/common/service.rb +219 -0
  63. data/lib/selenium/webdriver/common/socket_lock.rb +82 -0
  64. data/lib/selenium/webdriver/common/socket_poller.rb +47 -26
  65. data/lib/selenium/webdriver/common/target_locator.rb +35 -14
  66. data/lib/selenium/webdriver/common/timeouts.rb +23 -6
  67. data/lib/selenium/webdriver/common/touch_action_builder.rb +25 -11
  68. data/lib/selenium/webdriver/common/touch_screen.rb +42 -24
  69. data/lib/selenium/webdriver/common/w3c_action_builder.rb +212 -0
  70. data/lib/selenium/webdriver/common/w3c_manager.rb +45 -0
  71. data/lib/selenium/webdriver/common/wait.rb +34 -14
  72. data/lib/selenium/webdriver/common/window.rb +75 -16
  73. data/lib/selenium/webdriver/common/zipper.rb +26 -11
  74. data/lib/selenium/webdriver/common.rb +40 -7
  75. data/lib/selenium/webdriver/edge/bridge.rb +76 -0
  76. data/lib/selenium/webdriver/edge/driver.rb +66 -0
  77. data/lib/selenium/webdriver/edge/options.rb +80 -0
  78. data/lib/selenium/webdriver/edge/service.rb +52 -0
  79. data/lib/selenium/webdriver/edge.rb +44 -0
  80. data/lib/selenium/webdriver/firefox/binary.rb +70 -48
  81. data/lib/selenium/webdriver/firefox/driver.rb +50 -0
  82. data/lib/selenium/webdriver/firefox/extension/prefs.json +14 -13
  83. data/lib/selenium/webdriver/firefox/extension/webdriver.xpi +0 -0
  84. data/lib/selenium/webdriver/firefox/extension.rb +50 -19
  85. data/lib/selenium/webdriver/firefox/launcher.rb +33 -28
  86. data/lib/selenium/webdriver/firefox/legacy/driver.rb +83 -0
  87. data/lib/selenium/webdriver/firefox/marionette/bridge.rb +49 -0
  88. data/lib/selenium/webdriver/firefox/marionette/driver.rb +90 -0
  89. data/lib/selenium/webdriver/firefox/options.rb +162 -0
  90. data/lib/selenium/webdriver/firefox/profile.rb +66 -48
  91. data/lib/selenium/webdriver/firefox/profiles_ini.rb +28 -16
  92. data/lib/selenium/webdriver/firefox/service.rb +52 -0
  93. data/lib/selenium/webdriver/firefox/util.rb +19 -2
  94. data/lib/selenium/webdriver/firefox.rb +46 -10
  95. data/lib/selenium/webdriver/ie/driver.rb +85 -0
  96. data/lib/selenium/webdriver/ie/options.rb +138 -0
  97. data/lib/selenium/webdriver/ie/service.rb +54 -0
  98. data/lib/selenium/webdriver/ie.rb +32 -10
  99. data/lib/selenium/webdriver/remote/bridge.rb +117 -572
  100. data/lib/selenium/webdriver/remote/capabilities.rb +116 -99
  101. data/lib/selenium/webdriver/remote/driver.rb +51 -0
  102. data/lib/selenium/webdriver/remote/http/common.rb +54 -23
  103. data/lib/selenium/webdriver/remote/http/curb.rb +30 -12
  104. data/lib/selenium/webdriver/remote/http/default.rb +85 -42
  105. data/lib/selenium/webdriver/remote/http/persistent.rb +29 -7
  106. data/lib/selenium/webdriver/remote/oss/bridge.rb +594 -0
  107. data/lib/selenium/webdriver/remote/oss/commands.rb +223 -0
  108. data/lib/selenium/webdriver/remote/response.rb +68 -30
  109. data/lib/selenium/webdriver/remote/server_error.rb +22 -5
  110. data/lib/selenium/webdriver/remote/w3c/bridge.rb +605 -0
  111. data/lib/selenium/webdriver/remote/w3c/capabilities.rb +310 -0
  112. data/lib/selenium/webdriver/remote/w3c/commands.rb +157 -0
  113. data/lib/selenium/webdriver/remote.rb +27 -13
  114. data/lib/selenium/webdriver/safari/bridge.rb +38 -107
  115. data/lib/selenium/webdriver/safari/driver.rb +68 -0
  116. data/lib/selenium/webdriver/safari/options.rb +56 -75
  117. data/lib/selenium/webdriver/safari/service.rb +38 -0
  118. data/lib/selenium/webdriver/safari.rb +49 -31
  119. data/lib/selenium/webdriver/support/abstract_event_listener.rb +40 -6
  120. data/lib/selenium/webdriver/support/block_event_listener.rb +24 -7
  121. data/lib/selenium/webdriver/support/color.rb +82 -46
  122. data/lib/selenium/webdriver/support/escaper.rb +43 -0
  123. data/lib/selenium/webdriver/support/event_firing_bridge.rb +56 -39
  124. data/lib/selenium/webdriver/support/select.rb +66 -89
  125. data/lib/selenium/webdriver/support.rb +20 -0
  126. data/lib/selenium/webdriver/version.rb +24 -0
  127. data/lib/selenium/webdriver.rb +55 -25
  128. data/lib/selenium-webdriver.rb +19 -0
  129. data/selenium-webdriver.gemspec +42 -29
  130. metadata +331 -260
  131. data/Gemfile.lock +0 -48
  132. data/lib/selenium/client/base.rb +0 -132
  133. data/lib/selenium/client/driver.rb +0 -10
  134. data/lib/selenium/client/errors.rb +0 -9
  135. data/lib/selenium/client/extensions.rb +0 -118
  136. data/lib/selenium/client/idiomatic.rb +0 -488
  137. data/lib/selenium/client/javascript_expression_builder.rb +0 -116
  138. data/lib/selenium/client/javascript_frameworks/jquery.rb +0 -13
  139. data/lib/selenium/client/javascript_frameworks/prototype.rb +0 -13
  140. data/lib/selenium/client/legacy_driver.rb +0 -1720
  141. data/lib/selenium/client/protocol.rb +0 -104
  142. data/lib/selenium/client/selenium_helper.rb +0 -34
  143. data/lib/selenium/client.rb +0 -38
  144. data/lib/selenium/rake/server_task.rb +0 -157
  145. data/lib/selenium/webdriver/android/bridge.rb +0 -49
  146. data/lib/selenium/webdriver/android.rb +0 -9
  147. data/lib/selenium/webdriver/common/core_ext/base64.rb +0 -9
  148. data/lib/selenium/webdriver/common/core_ext/dir.rb +0 -42
  149. data/lib/selenium/webdriver/common/core_ext/string.rb +0 -5
  150. data/lib/selenium/webdriver/common/driver_extensions/has_browser_connection.rb +0 -17
  151. data/lib/selenium/webdriver/common/driver_extensions/has_input_devices.rb +0 -39
  152. data/lib/selenium/webdriver/common/html5/location.rb +0 -0
  153. data/lib/selenium/webdriver/common/json_helper.rb +0 -34
  154. data/lib/selenium/webdriver/firefox/bridge.rb +0 -70
  155. data/lib/selenium/webdriver/firefox/socket_lock.rb +0 -61
  156. data/lib/selenium/webdriver/ie/bridge.rb +0 -69
  157. data/lib/selenium/webdriver/ie/server.rb +0 -90
  158. data/lib/selenium/webdriver/iphone/bridge.rb +0 -45
  159. data/lib/selenium/webdriver/iphone.rb +0 -9
  160. data/lib/selenium/webdriver/opera/bridge.rb +0 -112
  161. data/lib/selenium/webdriver/opera/service.rb +0 -49
  162. data/lib/selenium/webdriver/opera.rb +0 -24
  163. data/lib/selenium/webdriver/phantomjs/bridge.rb +0 -59
  164. data/lib/selenium/webdriver/phantomjs/service.rb +0 -90
  165. data/lib/selenium/webdriver/phantomjs.rb +0 -22
  166. data/lib/selenium/webdriver/remote/commands.rb +0 -192
  167. data/lib/selenium/webdriver/safari/browser.rb +0 -20
  168. data/lib/selenium/webdriver/safari/extensions.rb +0 -170
  169. data/lib/selenium/webdriver/safari/resources/SafariDriver.safariextz +0 -0
  170. data/lib/selenium/webdriver/safari/resources/client.js +0 -6903
  171. data/lib/selenium/webdriver/safari/server.rb +0 -145
  172. data/lib/selenium-client.rb +0 -2
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
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
+ module Selenium
21
+ module WebDriver
22
+ module Support
23
+ module Escaper
24
+ def self.escape(str)
25
+ if str.include?('"') && str.include?("'")
26
+ parts = str.split('"', -1).map { |part| %("#{part}") }
27
+
28
+ quoted = parts.join(%(, '"', ))
29
+ .gsub(/^"", |, ""$/, '')
30
+
31
+ "concat(#{quoted})"
32
+ elsif str.include?('"')
33
+ # escape string with just a quote into being single quoted: f"oo -> 'f"oo'
34
+ "'#{str}'"
35
+ else
36
+ # otherwise return the quoted string
37
+ %("#{str}")
38
+ end
39
+ end
40
+ end # Escaper
41
+ end # Support
42
+ end # WebDriver
43
+ end # Selenium
@@ -1,7 +1,25 @@
1
+ # frozen_string_literal: true
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
+
1
20
  module Selenium
2
21
  module WebDriver
3
22
  module Support
4
-
5
23
  #
6
24
  # @api private
7
25
  #
@@ -10,69 +28,69 @@ module Selenium
10
28
  def initialize(delegate, listener)
11
29
  @delegate = delegate
12
30
 
13
- if listener.respond_to? :call
14
- @listener = BlockEventListener.new(listener)
15
- else
16
- @listener = listener
17
- end
31
+ @listener = if listener.respond_to? :call
32
+ BlockEventListener.new(listener)
33
+ else
34
+ listener
35
+ end
18
36
  end
19
37
 
20
38
  def get(url)
21
- dispatch(:navigate_to, url, driver) {
39
+ dispatch(:navigate_to, url, driver) do
22
40
  @delegate.get(url)
23
- }
41
+ end
24
42
  end
25
43
 
26
- def goForward
27
- dispatch(:navigate_forward, driver) {
28
- @delegate.goForward
29
- }
44
+ def go_forward
45
+ dispatch(:navigate_forward, driver) do
46
+ @delegate.go_forward
47
+ end
30
48
  end
31
49
 
32
- def goBack
33
- dispatch(:navigate_back, driver) {
34
- @delegate.goBack
35
- }
50
+ def go_back
51
+ dispatch(:navigate_back, driver) do
52
+ @delegate.go_back
53
+ end
36
54
  end
37
55
 
38
- def clickElement(ref)
39
- dispatch(:click, create_element(ref), driver) {
40
- @delegate.clickElement(ref)
41
- }
56
+ def click_element(ref)
57
+ dispatch(:click, create_element(ref), driver) do
58
+ @delegate.click_element(ref)
59
+ end
42
60
  end
43
61
 
44
- def clearElement(ref)
45
- dispatch(:change_value_of, create_element(ref), driver) {
46
- @delegate.clearElement(ref)
47
- }
62
+ def clear_element(ref)
63
+ dispatch(:change_value_of, create_element(ref), driver) do
64
+ @delegate.clear_element(ref)
65
+ end
48
66
  end
49
67
 
50
- def sendKeysToElement(ref, keys)
51
- dispatch(:change_value_of, create_element(ref), driver) {
52
- @delegate.sendKeysToElement(ref, keys)
53
- }
68
+ def send_keys_to_element(ref, keys)
69
+ dispatch(:change_value_of, create_element(ref), driver) do
70
+ @delegate.send_keys_to_element(ref, keys)
71
+ end
54
72
  end
55
73
 
56
74
  def find_element_by(how, what, parent = nil)
57
- e = dispatch(:find, how, what, driver) {
75
+ e = dispatch(:find, how, what, driver) do
58
76
  @delegate.find_element_by how, what, parent
59
- }
77
+ end
60
78
 
61
79
  Element.new self, e.ref
62
80
  end
63
81
 
64
82
  def find_elements_by(how, what, parent = nil)
65
- es = dispatch(:find, how, what, driver) {
83
+ es = dispatch(:find, how, what, driver) do
66
84
  @delegate.find_elements_by(how, what, parent)
67
- }
85
+ end
68
86
 
69
87
  es.map { |e| Element.new self, e.ref }
70
88
  end
71
89
 
72
- def executeScript(script, *args)
73
- dispatch(:execute_script, script, driver) {
74
- @delegate.executeScript(script, *args)
75
- }
90
+ def execute_script(script, *args)
91
+ dispatch(:execute_script, script, driver) do
92
+ @delegate.execute_script(script, *args)
93
+ end
76
94
  end
77
95
 
78
96
  def quit
@@ -94,7 +112,7 @@ module Selenium
94
112
  @driver ||= Driver.new(self)
95
113
  end
96
114
 
97
- def dispatch(name, *args, &blk)
115
+ def dispatch(name, *args)
98
116
  @listener.__send__("before_#{name}", *args)
99
117
  returned = yield
100
118
  @listener.__send__("after_#{name}", *args)
@@ -102,11 +120,10 @@ module Selenium
102
120
  returned
103
121
  end
104
122
 
105
- def method_missing(meth, *args, &blk)
123
+ def method_missing(meth, *args, &blk) # rubocop:disable Style/MethodMissingSuper, Style/MissingRespondToMissing
106
124
  @delegate.__send__(meth, *args, &blk)
107
125
  end
108
126
  end # EventFiringBridge
109
-
110
127
  end # Support
111
128
  end # WebDriver
112
129
  end # Selenium
@@ -1,8 +1,26 @@
1
+ # frozen_string_literal: true
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
+
1
20
  module Selenium
2
21
  module WebDriver
3
22
  module Support
4
23
  class Select
5
-
6
24
  #
7
25
  # @param [Element] element The select element to use
8
26
  #
@@ -10,12 +28,10 @@ module Selenium
10
28
  def initialize(element)
11
29
  tag_name = element.tag_name
12
30
 
13
- unless tag_name.downcase == "select"
14
- raise ArgumentError, "unexpected tag name #{tag_name.inspect}"
15
- end
31
+ raise ArgumentError, "unexpected tag name #{tag_name.inspect}" unless tag_name.casecmp('select').zero?
16
32
 
17
33
  @element = element
18
- @multi = ![nil, "false"].include?(element.attribute(:multiple))
34
+ @multi = ![nil, 'false'].include?(element.attribute(:multiple))
19
35
  end
20
36
 
21
37
  #
@@ -35,7 +51,7 @@ module Selenium
35
51
  #
36
52
 
37
53
  def options
38
- @element.find_elements :tag_name, 'option'
54
+ @element.find_elements tag_name: 'option'
39
55
  end
40
56
 
41
57
  #
@@ -45,7 +61,7 @@ module Selenium
45
61
  #
46
62
 
47
63
  def selected_options
48
- options.select { |e| e.selected? }
64
+ options.select(&:selected?)
49
65
  end
50
66
 
51
67
  #
@@ -56,8 +72,10 @@ module Selenium
56
72
  #
57
73
 
58
74
  def first_selected_option
59
- option = options.find { |e| e.selected? }
60
- option or raise Error::NoSuchElementError, 'no options are selected'
75
+ option = options.find(&:selected?)
76
+ return option if option
77
+
78
+ raise Error::NoSuchElementError, 'no options are selected'
61
79
  end
62
80
 
63
81
  #
@@ -98,6 +116,7 @@ module Selenium
98
116
  #
99
117
  # @param [:text, :index, :value] how How to find the option
100
118
  # @param [String] what What value to find the option by.
119
+ # @raise [Error::UnsupportedOperationError] if the element does not support multiple selections.
101
120
  #
102
121
  # @see Select#select_by
103
122
  #
@@ -122,9 +141,7 @@ module Selenium
122
141
  #
123
142
 
124
143
  def select_all
125
- unless multiple?
126
- raise Error::UnsupportedOperationError, 'you may only select all options of a multi-select'
127
- end
144
+ raise Error::UnsupportedOperationError, 'you may only select all options of a multi-select' unless multiple?
128
145
 
129
146
  options.each { |e| select_option e }
130
147
  end
@@ -136,9 +153,7 @@ module Selenium
136
153
  #
137
154
 
138
155
  def deselect_all
139
- unless multiple?
140
- raise Error::UnsupportedOperationError, 'you may only deselect all options of a multi-select'
141
- end
156
+ raise Error::UnsupportedOperationError, 'you may only deselect all options of a multi-select' unless multiple?
142
157
 
143
158
  options.each { |e| deselect_option e }
144
159
  end
@@ -148,65 +163,57 @@ module Selenium
148
163
  def select_by_text(text)
149
164
  opts = find_by_text text
150
165
 
151
- if opts.empty?
152
- raise Error::NoSuchElementError, "cannot locate element with text: #{text.inspect}"
153
- end
166
+ return select_options(opts) unless opts.empty?
154
167
 
155
- select_options opts
168
+ raise Error::NoSuchElementError, "cannot locate element with text: #{text.inspect}"
156
169
  end
157
170
 
158
171
  def select_by_index(index)
159
172
  opts = find_by_index index
160
173
 
161
- if opts.empty?
162
- raise Error::NoSuchElementError, "cannot locate element with index: #{index.inspect}"
163
- end
174
+ return select_option(opts.first) unless opts.empty?
164
175
 
165
- select_options opts
176
+ raise Error::NoSuchElementError, "cannot locate element with index: #{index.inspect}"
166
177
  end
167
178
 
168
179
  def select_by_value(value)
169
180
  opts = find_by_value value
170
181
 
171
- if opts.empty?
172
- raise Error::NoSuchElementError, "cannot locate option with value: #{value.inspect}"
173
- end
182
+ return select_options(opts) unless opts.empty?
174
183
 
175
- select_options opts
184
+ raise Error::NoSuchElementError, "cannot locate option with value: #{value.inspect}"
176
185
  end
177
186
 
178
187
  def deselect_by_text(text)
188
+ raise Error::UnsupportedOperationError, 'you may only deselect option of a multi-select' unless multiple?
189
+
179
190
  opts = find_by_text text
180
191
 
181
- if opts.empty?
182
- raise Error::NoSuchElementError, "cannot locate element with text: #{text.inspect}"
183
- end
192
+ return deselect_options(opts) unless opts.empty?
184
193
 
185
- deselect_options opts
194
+ raise Error::NoSuchElementError, "cannot locate element with text: #{text.inspect}"
186
195
  end
187
196
 
188
197
  def deselect_by_value(value)
198
+ raise Error::UnsupportedOperationError, 'you may only deselect option of a multi-select' unless multiple?
199
+
189
200
  opts = find_by_value value
190
201
 
191
- if opts.empty?
192
- raise Error::NoSuchElementError, "cannot locate option with value: #{value.inspect}"
193
- end
202
+ return deselect_options(opts) unless opts.empty?
194
203
 
195
- deselect_options opts
204
+ raise Error::NoSuchElementError, "cannot locate option with value: #{value.inspect}"
196
205
  end
197
206
 
198
207
  def deselect_by_index(index)
208
+ raise Error::UnsupportedOperationError, 'you may only deselect option of a multi-select' unless multiple?
209
+
199
210
  opts = find_by_index index
200
211
 
201
- if opts.empty?
202
- raise Error::NoSuchElementError, "cannot locate option with index: #{index}"
203
- end
212
+ return deselect_option(opts.first) unless opts.empty?
204
213
 
205
- deselect_options opts
214
+ raise Error::NoSuchElementError, "cannot locate option with index: #{index}"
206
215
  end
207
216
 
208
- private
209
-
210
217
  def select_option(option)
211
218
  option.click unless option.selected?
212
219
  end
@@ -233,61 +240,31 @@ module Selenium
233
240
 
234
241
  def find_by_text(text)
235
242
  xpath = ".//option[normalize-space(.) = #{Escaper.escape text}]"
236
- opts = @element.find_elements(:xpath, xpath)
237
-
238
- if opts.empty? && text =~ /\s+/
239
- longest_word = text.split(/\s+/).max_by { |item| item.length }
240
-
241
- if longest_word.empty?
242
- candidates = options
243
- else
244
- xpath = ".//option[contains(., #{Escaper.escape longest_word})]"
245
- candidates = @element.find_elements(:xpath, xpath)
246
- end
247
-
248
- if multiple?
249
- candidates.select { |option| text == option.text }
250
- else
251
- Array(candidates.find { |option| text == option.text })
252
- end
243
+ opts = @element.find_elements(xpath: xpath)
244
+
245
+ return opts unless opts.empty? && text =~ /\s+/
246
+
247
+ longest_word = text.split(/\s+/).max_by(&:length)
248
+ if longest_word.empty?
249
+ candidates = options
253
250
  else
254
- opts
251
+ xpath = ".//option[contains(., #{Escaper.escape longest_word})]"
252
+ candidates = @element.find_elements(xpath: xpath)
255
253
  end
254
+
255
+ return Array(candidates.find { |option| text == option.text }) unless multiple?
256
+
257
+ candidates.select { |option| text == option.text }
256
258
  end
257
259
 
258
260
  def find_by_index(index)
259
- index = index.to_s
260
- options.select { |option| option.attribute(:index) == index }
261
+ options.select { |option| option.attribute(:index) == index.to_s }
261
262
  end
262
263
 
263
264
  def find_by_value(value)
264
- @element.find_elements(:xpath, ".//option[@value = #{Escaper.escape value}]")
265
+ @element.find_elements(xpath: ".//option[@value = #{Escaper.escape value}]")
265
266
  end
266
-
267
- #
268
- # @api private
269
- #
270
-
271
- module Escaper
272
- def self.escape(str)
273
- if str.include?('"') && str.include?("'")
274
- parts = str.split('"', -1).map { |part| %{"#{part}"} }
275
-
276
- quoted = parts.join(%{, '"', }).
277
- gsub(/^"", |, ""$/, '')
278
-
279
- "concat(#{quoted})"
280
- elsif str.include?('"')
281
- # escape string with just a quote into being single quoted: f"oo -> 'f"oo'
282
- "'#{str}'"
283
- else
284
- # otherwise return the quoted string
285
- %{"#{str}"}
286
- end
287
- end
288
- end # Escaper
289
-
290
267
  end # Select
291
- end
292
- end
293
- end
268
+ end # Support
269
+ end # WebDriver
270
+ end # Selenium
@@ -1,5 +1,25 @@
1
+ # frozen_string_literal: true
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
+
1
20
  require 'selenium/webdriver/support/event_firing_bridge'
2
21
  require 'selenium/webdriver/support/abstract_event_listener'
3
22
  require 'selenium/webdriver/support/block_event_listener'
23
+ require 'selenium/webdriver/support/escaper'
4
24
  require 'selenium/webdriver/support/select'
5
25
  require 'selenium/webdriver/support/color'
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
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
+ module Selenium
21
+ module WebDriver
22
+ VERSION = '3.142.7'
23
+ end # WebDriver
24
+ end # Selenium
@@ -1,25 +1,44 @@
1
+ # frozen_string_literal: true
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
+
1
20
  require 'childprocess'
2
21
  require 'tmpdir'
3
22
  require 'fileutils'
4
23
  require 'date'
24
+ require 'json'
25
+ require 'set'
5
26
 
6
- require 'multi_json'
7
27
  require 'selenium/webdriver/common'
28
+ require 'selenium/webdriver/atoms'
29
+ require 'selenium/webdriver/version'
8
30
 
9
31
  module Selenium
10
32
  module WebDriver
11
- extend JsonHelper
12
-
13
33
  Point = Struct.new(:x, :y)
14
34
  Dimension = Struct.new(:width, :height)
35
+ Rectangle = Struct.new(:x, :y, :width, :height)
15
36
  Location = Struct.new(:latitude, :longitude, :altitude)
16
37
 
17
- autoload :Android, 'selenium/webdriver/android'
18
38
  autoload :Chrome, 'selenium/webdriver/chrome'
39
+ autoload :Edge, 'selenium/webdriver/edge'
19
40
  autoload :Firefox, 'selenium/webdriver/firefox'
20
41
  autoload :IE, 'selenium/webdriver/ie'
21
- autoload :IPhone, 'selenium/webdriver/iphone'
22
- autoload :Opera, 'selenium/webdriver/opera'
23
42
  autoload :PhantomJS, 'selenium/webdriver/phantomjs'
24
43
  autoload :Remote, 'selenium/webdriver/remote'
25
44
  autoload :Safari, 'selenium/webdriver/safari'
@@ -28,37 +47,39 @@ module Selenium
28
47
  # @api private
29
48
 
30
49
  def self.root
31
- @root ||= File.expand_path("../..", __FILE__)
50
+ @root ||= File.expand_path('..', __dir__)
32
51
  end
33
52
 
34
53
  #
35
54
  # Create a new Driver instance with the correct bridge for the given browser
36
55
  #
37
- # @param browser [:ie, :internet_explorer, :remote, :chrome, :firefox, :ff, :android, :iphone, :opera, :phantomjs, :safari]
38
- # the driver type to use
39
- # @param *rest
40
- # arguments passed to Bridge.new
56
+ # @overload for(browser)
57
+ # @param [:ie, :internet_explorer, :edge, :remote, :chrome, :firefox, :ff, :phantomjs, :safari] browser The browser to
58
+ # create the driver for
59
+ # @overload for(browser, opts)
60
+ # @param [:ie, :internet_explorer, :edge, :remote, :chrome, :firefox, :ff, :phantomjs, :safari] browser The browser to
61
+ # create the driver for
62
+ # @param [Hash] opts Options passed to Driver.new
41
63
  #
42
64
  # @return [Driver]
43
65
  #
44
- # @see Selenium::WebDriver::Remote::Bridge
45
- # @see Selenium::WebDriver::Firefox::Bridge
46
- # @see Selenium::WebDriver::IE::Bridge
47
- # @see Selenium::WebDriver::Chrome::Bridge
48
- # @see Selenium::WebDriver::Android::Bridge
49
- # @see Selenium::WebDriver::IPhone::Bridge
50
- # @see Selenium::WebDriver::Opera::Bridge
51
- # @see Selenium::WebDriver::PhantomJS::Bridge
52
- # @see Selenium::WebDriver::Safari::Bridge
66
+ # @see Selenium::WebDriver::Remote::Driver
67
+ # @see Selenium::WebDriver::Firefox::Driver
68
+ # @see Selenium::WebDriver::IE::Driver
69
+ # @see Selenium::WebDriver::Edge::Driver
70
+ # @see Selenium::WebDriver::Chrome::Driver
71
+ # @see Selenium::WebDriver::PhantomJS::Driver
72
+ # @see Selenium::WebDriver::Safari::Driver
53
73
  #
54
74
  # @example
55
75
  #
56
- # WebDriver.for :firefox, :profile => "some-profile"
57
- # WebDriver.for :firefox, :profile => Profile.new
58
- # WebDriver.for :remote, :url => "http://localhost:4444/wd/hub", :desired_capabilities => caps
76
+ # WebDriver.for :firefox, profile: 'some-profile'
77
+ # WebDriver.for :firefox, profile: Profile.new
78
+ # WebDriver.for :remote, url: "http://localhost:4444/wd/hub", desired_capabilities: caps
59
79
  #
60
- # One special argument is not passed on to the bridges, :listener. You can pass a listener for this option
61
- # to get notified of WebDriver events. The passed object must respond to #call or implement the methods from AbstractEventListener.
80
+ # One special argument is not passed on to the bridges, :listener.
81
+ # You can pass a listener for this option to get notified of WebDriver events.
82
+ # The passed object must respond to #call or implement the methods from AbstractEventListener.
62
83
  #
63
84
  # @see Selenium::WebDriver::Support::AbstractEventListener
64
85
  #
@@ -67,5 +88,14 @@ module Selenium
67
88
  WebDriver::Driver.for(*args)
68
89
  end
69
90
 
91
+ #
92
+ # Returns logger instance that can be used across the whole Selenium.
93
+ #
94
+ # @return [Logger]
95
+ #
96
+
97
+ def self.logger
98
+ @logger ||= WebDriver::Logger.new
99
+ end
70
100
  end # WebDriver
71
101
  end # Selenium
@@ -1 +1,20 @@
1
+ # frozen_string_literal: true
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
+
1
20
  require 'selenium/webdriver'