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
@@ -1,13 +1,34 @@
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 Firefox
4
-
23
+ #
5
24
  # @api private
25
+ #
26
+
6
27
  class Extension
28
+ NAMESPACE = 'http://www.mozilla.org/2004/em-rdf#'
29
+
7
30
  def initialize(path)
8
- unless File.exist?(path)
9
- raise Error::WebDriverError, "could not find extension at #{path.inspect}"
10
- end
31
+ raise Error::WebDriverError, "could not find extension at #{path.inspect}" unless File.exist?(path)
11
32
 
12
33
  @path = path
13
34
  @should_reap_root = false
@@ -15,10 +36,10 @@ module Selenium
15
36
 
16
37
  def write_to(extensions_dir)
17
38
  root_dir = create_root
18
- ext_path = File.join extensions_dir, read_id_from_install_rdf(root_dir)
39
+ ext_path = File.join extensions_dir, read_id(root_dir)
19
40
 
20
41
  FileUtils.rm_rf ext_path
21
- FileUtils.mkdir_p File.dirname(ext_path), :mode => 0700
42
+ FileUtils.mkdir_p File.dirname(ext_path), mode: 0o700
22
43
  FileUtils.cp_r root_dir, ext_path
23
44
 
24
45
  FileReaper.reap(root_dir) if @should_reap_root
@@ -31,7 +52,7 @@ module Selenium
31
52
  @path
32
53
  else
33
54
  unless Zipper::EXTENSIONS.include? File.extname(@path)
34
- raise Error::WebDriverError, "expected #{Zipper::EXTENSIONS.join(" or ")}, got #{@path.inspect}"
55
+ raise Error::WebDriverError, "expected #{Zipper::EXTENSIONS.join(' or ')}, got #{@path.inspect}"
35
56
  end
36
57
 
37
58
  @should_reap_root = true
@@ -39,25 +60,35 @@ module Selenium
39
60
  end
40
61
  end
41
62
 
42
- def read_id_from_install_rdf(directory)
43
- rdf_path = File.join(directory, "install.rdf")
44
- doc = REXML::Document.new(File.read(rdf_path))
63
+ def read_id(directory)
64
+ read_id_from_install_rdf(directory) || read_id_from_manifest_json(directory)
65
+ end
45
66
 
46
- id_node = REXML::XPath.first(doc, "//em:id")
67
+ def read_id_from_install_rdf(directory)
68
+ rdf_path = File.join(directory, 'install.rdf')
69
+ return unless File.exist?(rdf_path)
47
70
 
48
- if id_node
49
- id_node.text
50
- else
51
- attr_node = REXML::XPath.first(doc, "//@em:id")
71
+ doc = REXML::Document.new(File.read(rdf_path))
72
+ namespace = doc.root.namespaces.key(NAMESPACE)
52
73
 
53
- if attr_node.nil?
54
- raise Error::WebDriverError, "cannot locate extension id in #{rdf_path}"
55
- end
74
+ if namespace
75
+ id_node = REXML::XPath.first(doc, "//#{namespace}:id")
76
+ return id_node.text if id_node
56
77
 
57
- attr_node.value
78
+ attr_node = REXML::XPath.first(doc, "//@#{namespace}:id")
79
+ return attr_node.value if attr_node
58
80
  end
81
+
82
+ raise Error::WebDriverError, "cannot locate extension id in #{rdf_path}"
59
83
  end
60
84
 
85
+ def read_id_from_manifest_json(directory)
86
+ manifest_path = File.join(directory, 'manifest.json')
87
+ return unless File.exist?(manifest_path)
88
+
89
+ manifest = JSON.parse(File.read(manifest_path))
90
+ [manifest['name'].delete(' '), manifest['version']].join('@')
91
+ end
61
92
  end # Extension
62
93
  end # Firefox
63
94
  end # WebDriver
@@ -1,10 +1,27 @@
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 Firefox
4
-
5
23
  # @api private
6
24
  class Launcher
7
-
8
25
  SOCKET_LOCK_TIMEOUT = 45
9
26
  STABLE_CONNECTION_TIMEOUT = 60
10
27
 
@@ -14,14 +31,14 @@ module Selenium
14
31
 
15
32
  raise Error::WebDriverError, "invalid port: #{@port}" if @port < 1
16
33
 
17
- if profile.kind_of? Profile
34
+ if profile.is_a? Profile
18
35
  @profile = profile
19
36
  else
20
37
  @profile_name = profile
21
38
  @profile = nil
22
39
  end
23
40
 
24
- @host = "127.0.0.1"
41
+ @host = '127.0.0.1'
25
42
  end
26
43
 
27
44
  def url
@@ -32,7 +49,6 @@ module Selenium
32
49
  socket_lock.locked do
33
50
  find_free_port
34
51
  create_profile
35
- start_silent_and_wait
36
52
  start
37
53
  connect_until_stable
38
54
  end
@@ -61,45 +77,34 @@ module Selenium
61
77
 
62
78
  def start
63
79
  assert_profile
64
- @binary.start_with @profile, @profile_dir, "-foreground"
65
- end
66
-
67
- def start_silent_and_wait
68
- assert_profile
69
-
70
- @binary.start_with @profile, @profile_dir, "-silent"
71
- @binary.wait
80
+ @binary.start_with @profile, @profile_dir, '-foreground'
72
81
  end
73
82
 
74
83
  def connect_until_stable
75
84
  poller = SocketPoller.new(@host, @port, STABLE_CONNECTION_TIMEOUT)
76
85
 
77
- unless poller.connected?
78
- @binary.quit
79
- raise Error::WebDriverError, "unable to obtain stable firefox connection in #{STABLE_CONNECTION_TIMEOUT} seconds (#{@host}:#{@port})"
80
- end
86
+ return if poller.connected?
87
+
88
+ @binary.quit
89
+ error = "unable to obtain stable firefox connection in #{STABLE_CONNECTION_TIMEOUT} seconds (#{@host}:#{@port})"
90
+ raise Error::WebDriverError, error
81
91
  end
82
92
 
83
93
  def fetch_profile
84
- if @profile_name
85
- @profile = Profile.from_name @profile_name
86
-
87
- unless @profile
88
- raise Error::WebDriverError, "unable to find profile named: #{@profile_name.inspect}"
89
- end
90
- else
91
- @profile = Profile.new
92
- end
94
+ @profile = if @profile_name
95
+ Profile.from_name @profile_name
96
+ else
97
+ Profile.new
98
+ end
93
99
  end
94
100
 
95
101
  def assert_profile
96
- raise Error::WebDriverError, "must create_profile first" unless @profile && @profile_dir
102
+ raise Error::WebDriverError, 'must create_profile first' unless @profile && @profile_dir
97
103
  end
98
104
 
99
105
  def socket_lock
100
106
  @socket_lock ||= SocketLock.new(@port - 1, SOCKET_LOCK_TIMEOUT)
101
107
  end
102
-
103
108
  end # Launcher
104
109
  end # Firefox
105
110
  end # WebDriver
@@ -0,0 +1,83 @@
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 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 = {}) # rubocop:disable Metrics/AbcSize
34
+ WebDriver.logger.deprecate 'Selenium support for legacy Firefox', 'Firefox via marionette'
35
+
36
+ opts[:desired_capabilities] ||= Remote::Capabilities.firefox_legacy
37
+
38
+ if opts.key? :proxy
39
+ WebDriver.logger.deprecate ':proxy', "Selenium::WebDriver::Remote::Capabilities.firefox(proxy: #{opts[:proxy]})"
40
+ opts[:desired_capabilities].proxy = opts.delete(:proxy)
41
+ end
42
+
43
+ unless opts.key?(:url)
44
+ port = opts.delete(:port) || DEFAULT_PORT
45
+ profile = opts.delete(:profile)
46
+
47
+ Binary.path = opts[:desired_capabilities][:firefox_binary] if opts[:desired_capabilities][:firefox_binary]
48
+ @launcher = Launcher.new Binary.new, port, profile
49
+ @launcher.launch
50
+ opts[:url] = @launcher.url
51
+ end
52
+
53
+ listener = opts.delete(:listener)
54
+ WebDriver.logger.info 'Skipping handshake as we know it is OSS.'
55
+ desired_capabilities = opts.delete(:desired_capabilities)
56
+ bridge = Remote::Bridge.new(opts)
57
+ capabilities = bridge.create_session(desired_capabilities)
58
+ @bridge = Remote::OSS::Bridge.new(capabilities, bridge.session_id, opts)
59
+
60
+ begin
61
+ super(@bridge, listener: listener)
62
+ rescue
63
+ @launcher&.quit
64
+ raise
65
+ end
66
+ end
67
+
68
+ def browser
69
+ :firefox
70
+ end
71
+
72
+ def quit
73
+ super
74
+ nil
75
+ ensure
76
+ @launcher.quit
77
+ end
78
+
79
+ end # Driver
80
+ end # Legacy
81
+ end # Firefox
82
+ end # WebDriver
83
+ end # Selenium
@@ -0,0 +1,49 @@
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 Firefox
23
+ module Marionette
24
+ module Bridge
25
+
26
+ COMMANDS = {
27
+ install_addon: [:post, 'session/:session_id/moz/addon/install'],
28
+ uninstall_addon: [:post, 'session/:session_id/moz/addon/uninstall']
29
+ }.freeze
30
+
31
+ def commands(command)
32
+ COMMANDS[command] || super
33
+ end
34
+
35
+ def install_addon(path, temporary)
36
+ payload = {path: path}
37
+ payload[:temporary] = temporary unless temporary.nil?
38
+ execute :install_addon, {}, payload
39
+ end
40
+
41
+ def uninstall_addon(id)
42
+ execute :uninstall_addon, {}, {id: id}
43
+ end
44
+
45
+ end # Bridge
46
+ end # Marionette
47
+ end # Firefox
48
+ end # WebDriver
49
+ end # Selenium
@@ -0,0 +1,90 @@
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 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::HasAddons
32
+ include DriverExtensions::HasWebStorage
33
+ include DriverExtensions::TakesScreenshot
34
+
35
+ def initialize(opts = {})
36
+ opts[:desired_capabilities] = create_capabilities(opts)
37
+
38
+ opts[:url] ||= service_url(opts)
39
+
40
+ listener = opts.delete(:listener)
41
+ WebDriver.logger.info 'Skipping handshake as we know it is W3C.'
42
+ desired_capabilities = opts.delete(:desired_capabilities)
43
+ bridge = Remote::Bridge.new(opts)
44
+ capabilities = bridge.create_session(desired_capabilities)
45
+ @bridge = Remote::W3C::Bridge.new(capabilities, bridge.session_id, **opts)
46
+ @bridge.extend Marionette::Bridge
47
+
48
+ super(@bridge, listener: listener)
49
+ end
50
+
51
+ def browser
52
+ :firefox
53
+ end
54
+
55
+ def quit
56
+ super
57
+ ensure
58
+ @service&.stop
59
+ end
60
+
61
+ private
62
+
63
+ def create_capabilities(opts)
64
+ caps = opts.delete(:desired_capabilities) { Remote::Capabilities.firefox }
65
+ options = opts.delete(:options) { Options.new }
66
+
67
+ firefox_options = opts.delete(:firefox_options)
68
+ if firefox_options
69
+ WebDriver.logger.deprecate ':firefox_options', 'Selenium::WebDriver::Firefox::Options'
70
+ firefox_options.each do |key, value|
71
+ options.add_option(key, value)
72
+ end
73
+ end
74
+
75
+ profile = opts.delete(:profile)
76
+ if profile
77
+ WebDriver.logger.deprecate ':profile', 'Selenium::WebDriver::Firefox::Options#profile='
78
+ options.profile = profile
79
+ end
80
+
81
+ options = options.as_json
82
+ caps.merge!(options) unless options.empty?
83
+
84
+ caps
85
+ end
86
+ end # Driver
87
+ end # Marionette
88
+ end # Firefox
89
+ end # WebDriver
90
+ end # Selenium
@@ -0,0 +1,162 @@
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 Firefox
23
+ class Options < WebDriver::Common::Options
24
+ attr_reader :args, :prefs, :options, :profile
25
+ attr_accessor :binary, :log_level
26
+
27
+ KEY = 'moz:firefoxOptions'
28
+
29
+ #
30
+ # Create a new Options instance, only for W3C-capable versions of Firefox.
31
+ #
32
+ # @example
33
+ # options = Selenium::WebDriver::Firefox::Options.new(args: ['--host=127.0.0.1'])
34
+ # driver = Selenium::WebDriver.for :firefox, options: options
35
+ #
36
+ # @param [Hash] opts the pre-defined options to create the Firefox::Options with
37
+ # @option opts [String] :binary Path to the Firefox executable to use
38
+ # @option opts [Array<String>] :args List of command-line arguments to use when starting geckodriver
39
+ # @option opts [Profile, String] :profile Encoded profile string or Profile instance
40
+ # @option opts [String, Symbol] :log_level Log level for geckodriver
41
+ # @option opts [Hash] :prefs A hash with each entry consisting of the key of the preference and its value
42
+ # @option opts [Hash] :options A hash for raw options
43
+ #
44
+
45
+ def initialize(**opts)
46
+ @args = Set.new(opts.delete(:args) || [])
47
+ @binary = opts.delete(:binary)
48
+ @profile = process_profile(opts.delete(:profile))
49
+ @log_level = opts.delete(:log_level)
50
+ @prefs = opts.delete(:prefs) || {}
51
+ @options = opts.delete(:options) || {}
52
+ end
53
+
54
+ #
55
+ # Add a command-line argument to use when starting Firefox.
56
+ #
57
+ # @example Start geckodriver on a specific host
58
+ # options = Selenium::WebDriver::Firefox::Options.new
59
+ # options.add_argument('--host=127.0.0.1')
60
+ #
61
+ # @param [String] arg The command-line argument to add
62
+ #
63
+
64
+ def add_argument(arg)
65
+ @args << arg
66
+ end
67
+
68
+ #
69
+ # Add a new option not yet handled by these bindings.
70
+ #
71
+ # @example
72
+ # options = Selenium::WebDriver::Firefox::Options.new
73
+ # options.add_option(:foo, 'bar')
74
+ #
75
+ # @param [String, Symbol] name Name of the option
76
+ # @param [Boolean, String, Integer] value Value of the option
77
+ #
78
+
79
+ def add_option(name, value)
80
+ @options[name] = value
81
+ end
82
+
83
+ #
84
+ # Add a preference that is only applied to the user profile in use.
85
+ #
86
+ # @example Set the default homepage
87
+ # options = Selenium::WebDriver::Firefox::Options.new
88
+ # options.add_preference('browser.startup.homepage', 'http://www.seleniumhq.com/')
89
+ #
90
+ # @param [String] name Key of the preference
91
+ # @param [Boolean, String, Integer] value Value of the preference
92
+ #
93
+
94
+ def add_preference(name, value)
95
+ prefs[name] = value
96
+ end
97
+
98
+ #
99
+ # Run Firefox in headless mode.
100
+ #
101
+ # @example Enable headless mode
102
+ # options = Selenium::WebDriver::Firefox::Options.new
103
+ # options.headless!
104
+ #
105
+
106
+ def headless!
107
+ add_argument '-headless'
108
+ end
109
+
110
+ #
111
+ # Sets Firefox profile.
112
+ #
113
+ # @example Set the custom profile
114
+ # profile = Selenium::WebDriver::Firefox::Profile.new
115
+ # options = Selenium::WebDriver::Firefox::Options.new
116
+ # options.profile = profile
117
+ #
118
+ # @example Use existing profile
119
+ # options = Selenium::WebDriver::Firefox::Options.new
120
+ # options.profile = 'myprofile'
121
+ #
122
+ # @param [Profile, String] profile Profile to be used
123
+ #
124
+
125
+ def profile=(profile)
126
+ @profile = process_profile(profile)
127
+ end
128
+
129
+ #
130
+ # @api private
131
+ #
132
+
133
+ def as_json(*)
134
+ opts = @options
135
+
136
+ opts[:profile] = @profile.encoded if @profile
137
+ opts[:args] = @args.to_a if @args.any?
138
+ opts[:binary] = @binary if @binary
139
+ opts[:prefs] = @prefs unless @prefs.empty?
140
+ opts[:log] = {level: @log_level} if @log_level
141
+
142
+ {KEY => generate_as_json(opts)}
143
+ end
144
+
145
+ private
146
+
147
+ def process_profile(profile)
148
+ return unless profile
149
+
150
+ case profile
151
+ when Profile
152
+ profile
153
+ when String
154
+ Profile.from_name(profile)
155
+ else
156
+ raise Error::WebDriverError, "don't know how to handle profile: #{profile.inspect}"
157
+ end
158
+ end
159
+ end # Options
160
+ end # Firefox
161
+ end # WebDriver
162
+ end # Selenium