selenium-webdriver 3.4.0 → 3.4.1

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 (44) hide show
  1. data/CHANGES +35 -1
  2. data/Gemfile.lock +54 -0
  3. data/lib/selenium/webdriver.rb +8 -10
  4. data/lib/selenium/webdriver/chrome.rb +2 -1
  5. data/lib/selenium/webdriver/chrome/{bridge.rb → driver.rb} +47 -32
  6. data/lib/selenium/webdriver/chrome/options.rb +170 -0
  7. data/lib/selenium/webdriver/common/driver.rb +20 -39
  8. data/lib/selenium/webdriver/common/driver_extensions/takes_screenshot.rb +5 -0
  9. data/lib/selenium/webdriver/common/element.rb +5 -1
  10. data/lib/selenium/webdriver/common/logger.rb +10 -0
  11. data/lib/selenium/webdriver/common/w3c_error.rb +2 -2
  12. data/lib/selenium/webdriver/edge.rb +2 -1
  13. data/lib/selenium/webdriver/edge/bridge.rb +2 -91
  14. data/lib/selenium/webdriver/edge/driver.rb +80 -0
  15. data/lib/selenium/webdriver/firefox.rb +6 -3
  16. data/lib/selenium/webdriver/firefox/driver.rb +50 -0
  17. data/lib/selenium/webdriver/firefox/extension/webdriver.xpi +0 -0
  18. data/lib/selenium/webdriver/firefox/legacy/driver.rb +81 -0
  19. data/lib/selenium/webdriver/firefox/marionette/driver.rb +101 -0
  20. data/lib/selenium/webdriver/firefox/options.rb +139 -0
  21. data/lib/selenium/webdriver/ie.rb +1 -1
  22. data/lib/selenium/webdriver/ie/{bridge.rb → driver.rb} +13 -13
  23. data/lib/selenium/webdriver/phantomjs.rb +1 -1
  24. data/lib/selenium/webdriver/phantomjs/{bridge.rb → driver.rb} +10 -13
  25. data/lib/selenium/webdriver/remote.rb +11 -13
  26. data/lib/selenium/webdriver/remote/bridge.rb +87 -586
  27. data/lib/selenium/webdriver/remote/capabilities.rb +3 -1
  28. data/lib/selenium/webdriver/remote/driver.rb +44 -0
  29. data/lib/selenium/webdriver/remote/http/default.rb +1 -1
  30. data/lib/selenium/webdriver/remote/oss/bridge.rb +586 -0
  31. data/lib/selenium/webdriver/remote/{commands.rb → oss/commands.rb} +9 -5
  32. data/lib/selenium/webdriver/remote/oss/driver.rb +44 -0
  33. data/lib/selenium/webdriver/remote/w3c/bridge.rb +573 -0
  34. data/lib/selenium/webdriver/remote/w3c/capabilities.rb +266 -0
  35. data/lib/selenium/webdriver/remote/{w3c_commands.rb → w3c/commands.rb} +9 -4
  36. data/lib/selenium/webdriver/remote/w3c/driver.rb +41 -0
  37. data/lib/selenium/webdriver/safari.rb +3 -6
  38. data/lib/selenium/webdriver/safari/{bridge.rb → driver.rb} +14 -6
  39. data/selenium-webdriver.gemspec +1 -3
  40. metadata +29 -45
  41. data/lib/selenium/webdriver/firefox/bridge.rb +0 -70
  42. data/lib/selenium/webdriver/firefox/w3c_bridge.rb +0 -114
  43. data/lib/selenium/webdriver/remote/w3c_bridge.rb +0 -663
  44. data/lib/selenium/webdriver/remote/w3c_capabilities.rb +0 -231
@@ -32,6 +32,11 @@ module Selenium
32
32
  #
33
33
 
34
34
  def save_screenshot(png_path)
35
+ extension = File.extname(png_path).downcase
36
+ if extension != '.png'
37
+ WebDriver.logger.warn "name used for saved screenshot does not match file type. "\
38
+ "It should end with .png extension"
39
+ end
35
40
  File.open(png_path, 'wb') { |f| f << screenshot_as(:png) }
36
41
  end
37
42
 
@@ -312,7 +312,11 @@ module Selenium
312
312
  #
313
313
 
314
314
  def as_json(*)
315
- key = bridge.is_a?(Remote::W3CBridge) ? 'element-6066-11e4-a52e-4f735466cecf' : 'ELEMENT'
315
+ key = if bridge.dialect == :w3c
316
+ 'element-6066-11e4-a52e-4f735466cecf'
317
+ else
318
+ 'ELEMENT'
319
+ end
316
320
  @id.is_a?(Hash) ? @id : {key => @id}
317
321
  end
318
322
 
@@ -104,6 +104,16 @@ module Selenium
104
104
  end
105
105
  end
106
106
 
107
+ #
108
+ # Marks code as deprecated with replacement.
109
+ #
110
+ # @param [String] old
111
+ # @param [String] new
112
+ #
113
+ def deprecate(old, new)
114
+ warn "[DEPRECATION] #{old} is deprecated. Use #{new} instead."
115
+ end
116
+
107
117
  private
108
118
 
109
119
  def create_logger(output)
@@ -183,13 +183,13 @@ module Selenium
183
183
  # is obscuring the element that was requested clicked.
184
184
  #
185
185
 
186
- class ElementClickIntercepted < WebDriverError; end
186
+ class ElementClickInterceptedError < WebDriverError; end
187
187
 
188
188
  #
189
189
  # Indicates that a command could not be completed because the element is not pointer or keyboard interactable.
190
190
  #
191
191
 
192
- class ElementNotInteractable < WebDriverError; end
192
+ class ElementNotInteractableError < WebDriverError; end
193
193
 
194
194
  # aliased for backwards compatibility
195
195
  NoAlertPresentError = NoSuchAlertError
@@ -19,8 +19,9 @@
19
19
 
20
20
  require 'net/http'
21
21
 
22
- require 'selenium/webdriver/edge/service'
23
22
  require 'selenium/webdriver/edge/bridge'
23
+ require 'selenium/webdriver/edge/driver'
24
+ require 'selenium/webdriver/edge/service'
24
25
 
25
26
  module Selenium
26
27
  module WebDriver
@@ -20,42 +20,7 @@
20
20
  module Selenium
21
21
  module WebDriver
22
22
  module Edge
23
- #
24
- # @api private
25
- #
26
-
27
- class Bridge < Remote::W3CBridge
28
- def initialize(opts = {})
29
- opts[:desired_capabilities] ||= Remote::W3CCapabilities.edge
30
-
31
- unless opts.key?(:url)
32
- driver_path = opts.delete(:driver_path) || Edge.driver_path
33
- port = opts.delete(:port) || Service::DEFAULT_PORT
34
-
35
- opts[:driver_opts] ||= {}
36
- if opts.key? :service_args
37
- WebDriver.logger.warn <<-DEPRECATE.gsub(/\n +| {2,}/, ' ').freeze
38
- [DEPRECATION] `:service_args` is deprecated. Pass switches using `driver_opts`
39
- DEPRECATE
40
- opts[:driver_opts][:args] = opts.delete(:service_args)
41
- end
42
-
43
- @service = Service.new(driver_path, port, opts.delete(:driver_opts))
44
- @service.host = 'localhost' if @service.host == '127.0.0.1'
45
- @service.start
46
- opts[:url] = @service.uri
47
- end
48
-
49
- super(opts)
50
- end
51
-
52
- def browser
53
- :edge
54
- end
55
-
56
- def driver_extensions
57
- [DriverExtensions::TakesScreenshot]
58
- end
23
+ module Bridge
59
24
 
60
25
  def commands(command)
61
26
  unsupported = %i[execute_script execute_async_script submit_element double_click
@@ -64,21 +29,10 @@ module Selenium
64
29
  get_window_size set_window_size get_window_position set_window_position
65
30
  maximize_window get_alert_text accept_alert dismiss_alert]
66
31
  if unsupported.include? command
67
- Remote::Bridge::COMMANDS[command]
32
+ Remote::OSS::Bridge::COMMANDS[command]
68
33
  else
69
34
  super
70
35
  end
71
-
72
- end
73
-
74
- def capabilities
75
- @capabilities ||= Remote::Capabilities.edge
76
- end
77
-
78
- def quit
79
- super
80
- ensure
81
- @service.stop if @service
82
36
  end
83
37
 
84
38
  def send_keys_to_active_element(key)
@@ -116,49 +70,6 @@ module Selenium
116
70
  execute :maximize_window, window_handle: handle
117
71
  end
118
72
 
119
- def create_session(desired_capabilities)
120
- resp = raw_execute :new_session, {}, {desiredCapabilities: desired_capabilities}
121
- @session_id = resp['sessionId']
122
- return Remote::W3CCapabilities.json_create resp['value'] if @session_id
123
-
124
- raise Error::WebDriverError, 'no sessionId in returned payload'
125
- end
126
-
127
- #
128
- # executes a command on the remote server.
129
- #
130
- #
131
- # Returns the 'value' of the returned payload
132
- #
133
-
134
- def execute(*args)
135
- result = raw_execute(*args)
136
- result.payload.key?('value') ? result['value'] : result
137
- end
138
-
139
- #
140
- # executes a command on the remote server.
141
- #
142
- # @return [WebDriver::Remote::Response]
143
- #
144
-
145
- def raw_execute(command, opts = {}, command_hash = nil)
146
- verb, path = commands(command) || raise(ArgumentError, "unknown command: #{command.inspect}")
147
- path = path.dup
148
-
149
- path[':session_id'] = @session_id if path.include?(':session_id')
150
-
151
- begin
152
- opts.each do |key, value|
153
- path[key.inspect] = escaper.escape(value.to_s)
154
- end
155
- rescue IndexError
156
- raise ArgumentError, "#{opts.inspect} invalid for #{command.inspect}"
157
- end
158
-
159
- WebDriver.logger.info("-> #{verb.to_s.upcase} #{path}")
160
- http.call verb, path, command_hash
161
- end
162
73
  end # Bridge
163
74
  end # Edge
164
75
  end # WebDriver
@@ -0,0 +1,80 @@
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
+ module Selenium
21
+ module WebDriver
22
+ module Edge
23
+
24
+ #
25
+ # Driver implementation for Microsoft Edge.
26
+ # @api private
27
+ #
28
+
29
+ class Driver < WebDriver::Driver
30
+ include DriverExtensions::TakesScreenshot
31
+
32
+ def initialize(opts = {})
33
+ opts[:desired_capabilities] ||= Remote::W3C::Capabilities.edge
34
+
35
+ unless opts.key?(:url)
36
+ driver_path = opts.delete(:driver_path) || Edge.driver_path
37
+ port = opts.delete(:port) || Service::DEFAULT_PORT
38
+
39
+ opts[:driver_opts] ||= {}
40
+ if opts.key? :service_args
41
+ WebDriver.logger.deprecate ':service_args', "driver_opts: {args: #{opts[:service_args]}}"
42
+ opts[:driver_opts][:args] = opts.delete(:service_args)
43
+ end
44
+
45
+ @service = Service.new(driver_path, port, opts.delete(:driver_opts))
46
+ @service.host = 'localhost' if @service.host == '127.0.0.1'
47
+ @service.start
48
+ opts[:url] = @service.uri
49
+ end
50
+
51
+ listener = opts.delete(:listener)
52
+
53
+ # Edge is mostly using W3C dialect, but a request to
54
+ # create session responds with OSS-like body,
55
+ # so we need to force W3C implementation.
56
+ desired_capabilities = opts.delete(:desired_capabilities)
57
+ bridge = Remote::Bridge.new(opts)
58
+ capabilities = bridge.create_session(desired_capabilities)
59
+
60
+ WebDriver.logger.info 'Forcing W3C dialect.'
61
+ @bridge = Remote::W3C::Bridge.new(capabilities, bridge.session_id, opts)
62
+ @bridge.extend Edge::Bridge
63
+
64
+ super(@bridge, listener: listener)
65
+ end
66
+
67
+ def browser
68
+ :edge
69
+ end
70
+
71
+ def quit
72
+ super
73
+ ensure
74
+ @service.stop if @service
75
+ end
76
+
77
+ end # Driver
78
+ end # Edge
79
+ end # WebDriver
80
+ end # Selenium
@@ -21,15 +21,18 @@ require 'timeout'
21
21
  require 'socket'
22
22
  require 'rexml/document'
23
23
 
24
+ require 'selenium/webdriver/firefox/driver'
25
+
24
26
  require 'selenium/webdriver/firefox/util'
25
27
  require 'selenium/webdriver/firefox/extension'
26
28
  require 'selenium/webdriver/firefox/binary'
27
29
  require 'selenium/webdriver/firefox/profiles_ini'
28
30
  require 'selenium/webdriver/firefox/profile'
29
31
  require 'selenium/webdriver/firefox/launcher'
30
- require 'selenium/webdriver/firefox/bridge'
31
- require 'selenium/webdriver/firefox/w3c_bridge'
32
- require 'selenium/webdriver/firefox/binary'
32
+ require 'selenium/webdriver/firefox/legacy/driver'
33
+
34
+ require 'selenium/webdriver/firefox/marionette/driver'
35
+ require 'selenium/webdriver/firefox/options'
33
36
  require 'selenium/webdriver/firefox/service'
34
37
 
35
38
  module Selenium
@@ -0,0 +1,50 @@
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
+ module Selenium
21
+ module WebDriver
22
+ module Firefox
23
+ module Driver
24
+ class << self
25
+
26
+ #
27
+ # Instantiates correct Firefox driver implementation
28
+ # @return [Marionette::Driver, Legacy::Driver]
29
+ #
30
+
31
+ def new(**opts)
32
+ if marionette?(opts)
33
+ Firefox::Marionette::Driver.new(opts)
34
+ else
35
+ Firefox::Legacy::Driver.new(opts)
36
+ end
37
+ end
38
+
39
+ private
40
+
41
+ def marionette?(opts)
42
+ opts.delete(:marionette) != false &&
43
+ (!opts[:desired_capabilities] || opts[:desired_capabilities][:marionette] != false)
44
+ end
45
+ end
46
+
47
+ end # Driver
48
+ end # Firefox
49
+ end # WebDriver
50
+ end # Selenium
@@ -0,0 +1,81 @@
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
+ module Selenium
21
+ module WebDriver
22
+ module Firefox
23
+ module Legacy
24
+
25
+ #
26
+ # Driver implementation for Firefox using legacy extension.
27
+ # @api private
28
+ #
29
+
30
+ class Driver < WebDriver::Driver
31
+ include DriverExtensions::TakesScreenshot
32
+
33
+ def initialize(opts = {})
34
+ opts[:desired_capabilities] ||= Remote::Capabilities.firefox
35
+
36
+ if opts.key? :proxy
37
+ WebDriver.logger.deprecate ':proxy', "Selenium::WebDriver::Remote::Capabilities.firefox(proxy: #{opts[:proxy]})"
38
+ opts[:desired_capabilities].proxy = opts.delete(:proxy)
39
+ end
40
+
41
+ unless opts.key?(:url)
42
+ port = opts.delete(:port) || DEFAULT_PORT
43
+ profile = opts.delete(:profile)
44
+
45
+ Binary.path = opts[:desired_capabilities][:firefox_binary] if opts[:desired_capabilities][:firefox_binary]
46
+ @launcher = Launcher.new Binary.new, port, profile
47
+ @launcher.launch
48
+ opts[:url] = @launcher.url
49
+ end
50
+
51
+ listener = opts.delete(:listener)
52
+ WebDriver.logger.info 'Skipping handshake as we know it is OSS.'
53
+ desired_capabilities = opts.delete(:desired_capabilities)
54
+ bridge = Remote::Bridge.new(opts)
55
+ capabilities = bridge.create_session(desired_capabilities)
56
+ @bridge = Remote::OSS::Bridge.new(capabilities, bridge.session_id, opts)
57
+
58
+ begin
59
+ super(@bridge, listener: listener)
60
+ rescue
61
+ @launcher.quit if @launcher
62
+ raise
63
+ end
64
+ end
65
+
66
+ def browser
67
+ :firefox
68
+ end
69
+
70
+ def quit
71
+ super
72
+ nil
73
+ ensure
74
+ @launcher.quit
75
+ end
76
+
77
+ end # Driver
78
+ end # Legacy
79
+ end # Firefox
80
+ end # WebDriver
81
+ end # Selenium
@@ -0,0 +1,101 @@
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
+ module Selenium
21
+ module WebDriver
22
+ module Firefox
23
+ module Marionette
24
+
25
+ #
26
+ # Driver implementation for Firefox using GeckoDriver.
27
+ # @api private
28
+ #
29
+
30
+ class Driver < WebDriver::Driver
31
+ include DriverExtensions::HasWebStorage
32
+ include DriverExtensions::TakesScreenshot
33
+
34
+ def initialize(opts = {})
35
+ opts[:desired_capabilities] = create_capabilities(opts)
36
+
37
+ unless opts.key?(:url)
38
+ driver_path = opts.delete(:driver_path) || Firefox.driver_path
39
+ port = opts.delete(:port) || Service::DEFAULT_PORT
40
+
41
+ opts[:driver_opts] ||= {}
42
+ if opts.key? :service_args
43
+ WebDriver.logger.deprecate ':service_args', "driver_opts: {args: #{opts[:service_args]}}"
44
+ opts[:driver_opts][:args] = opts.delete(:service_args)
45
+ end
46
+
47
+ @service = Service.new(driver_path, port, opts.delete(:driver_opts))
48
+ @service.start
49
+ opts[:url] = @service.uri
50
+ end
51
+
52
+ listener = opts.delete(:listener)
53
+ WebDriver.logger.info 'Skipping handshake as we know it is W3C.'
54
+ desired_capabilities = opts.delete(:desired_capabilities)
55
+ bridge = Remote::Bridge.new(opts)
56
+ capabilities = bridge.create_session(desired_capabilities)
57
+ @bridge = Remote::W3C::Bridge.new(capabilities, bridge.session_id, opts)
58
+
59
+ super(@bridge, listener: listener)
60
+ end
61
+
62
+ def browser
63
+ :firefox
64
+ end
65
+
66
+ def quit
67
+ super
68
+ ensure
69
+ @service.stop if @service
70
+ end
71
+
72
+ private
73
+
74
+ def create_capabilities(opts)
75
+ caps = opts.delete(:desired_capabilities) { Remote::W3C::Capabilities.firefox }
76
+ options = opts.delete(:options) { Options.new }
77
+
78
+ firefox_options = opts.delete(:firefox_options)
79
+ if firefox_options
80
+ WebDriver.logger.deprecate ':firefox_options', 'Selenium::WebDriver::Firefox::Options'
81
+ firefox_options.each do |key, value|
82
+ options.add_option(key, value)
83
+ end
84
+ end
85
+
86
+ profile = opts.delete(:profile)
87
+ if profile
88
+ WebDriver.logger.deprecate ':profile', 'Selenium::WebDriver::Firefox::Options#profile='
89
+ options.profile = profile
90
+ end
91
+
92
+ options = options.as_json
93
+ caps.merge!(options) unless options.empty?
94
+
95
+ caps
96
+ end
97
+ end # Driver
98
+ end # Marionette
99
+ end # Firefox
100
+ end # WebDriver
101
+ end # Selenium