selenium-webdriver 2.45.0 → 3.142.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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'