selenium-webdriver 2.53.4 → 3.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (152) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGES +363 -10
  3. data/LICENSE +1 -1
  4. data/README.md +2 -3
  5. data/lib/selenium-webdriver.rb +0 -2
  6. data/lib/selenium/server.rb +69 -70
  7. data/lib/selenium/webdriver.rb +32 -23
  8. data/lib/selenium/webdriver/atoms.rb +18 -0
  9. data/lib/selenium/webdriver/atoms/getAttribute.js +8 -0
  10. data/lib/selenium/webdriver/chrome.rb +8 -6
  11. data/lib/selenium/webdriver/chrome/driver.rb +112 -0
  12. data/lib/selenium/webdriver/chrome/options.rb +168 -0
  13. data/lib/selenium/webdriver/chrome/profile.rb +17 -17
  14. data/lib/selenium/webdriver/chrome/service.rb +22 -89
  15. data/lib/selenium/webdriver/common.rb +13 -6
  16. data/lib/selenium/webdriver/common/action_builder.rb +49 -57
  17. data/lib/selenium/webdriver/common/alert.rb +5 -15
  18. data/lib/selenium/webdriver/common/bridge_helper.rb +10 -17
  19. data/lib/selenium/webdriver/common/driver.rb +53 -68
  20. data/lib/selenium/webdriver/common/driver_extensions/{has_input_devices.rb → has_addons.rb} +13 -23
  21. data/lib/selenium/webdriver/common/driver_extensions/has_location.rb +4 -8
  22. data/lib/selenium/webdriver/common/driver_extensions/has_network_connection.rb +4 -7
  23. data/lib/selenium/webdriver/common/driver_extensions/has_remote_status.rb +0 -4
  24. data/lib/selenium/webdriver/common/driver_extensions/has_session_id.rb +0 -4
  25. data/lib/selenium/webdriver/common/driver_extensions/has_touch_screen.rb +1 -5
  26. data/lib/selenium/webdriver/common/driver_extensions/has_web_storage.rb +0 -5
  27. data/lib/selenium/webdriver/common/driver_extensions/rotatable.rb +4 -9
  28. data/lib/selenium/webdriver/common/driver_extensions/takes_screenshot.rb +7 -7
  29. data/lib/selenium/webdriver/common/driver_extensions/uploads_files.rb +2 -7
  30. data/lib/selenium/webdriver/common/element.rb +57 -39
  31. data/lib/selenium/webdriver/common/error.rb +204 -106
  32. data/lib/selenium/webdriver/common/file_reaper.rb +3 -11
  33. data/lib/selenium/webdriver/common/html5/local_storage.rb +6 -10
  34. data/lib/selenium/webdriver/common/html5/session_storage.rb +6 -10
  35. data/lib/selenium/webdriver/common/html5/shared_web_storage.rb +7 -18
  36. data/lib/selenium/webdriver/{safari/options.rb → common/interactions/input_device.rb} +20 -31
  37. data/lib/selenium/webdriver/common/interactions/interaction.rb +50 -0
  38. data/lib/selenium/webdriver/{safari/browser.rb → common/interactions/interactions.rb} +16 -15
  39. data/lib/selenium/webdriver/common/interactions/key_actions.rb +143 -0
  40. data/lib/selenium/webdriver/common/interactions/key_input.rb +62 -0
  41. data/lib/selenium/webdriver/{android.rb → common/interactions/none_input.rb} +11 -6
  42. data/lib/selenium/webdriver/common/interactions/pointer_actions.rb +353 -0
  43. data/lib/selenium/webdriver/common/interactions/pointer_input.rb +132 -0
  44. data/lib/selenium/webdriver/common/keyboard.rb +7 -14
  45. data/lib/selenium/webdriver/common/keys.rb +99 -82
  46. data/lib/selenium/webdriver/common/log_entry.rb +3 -6
  47. data/lib/selenium/webdriver/common/logger.rb +140 -0
  48. data/lib/selenium/webdriver/common/logs.rb +2 -6
  49. data/lib/selenium/webdriver/common/mouse.rb +9 -14
  50. data/lib/selenium/webdriver/common/navigation.rb +2 -6
  51. data/lib/selenium/webdriver/common/options.rb +20 -23
  52. data/lib/selenium/webdriver/common/platform.rb +70 -97
  53. data/lib/selenium/webdriver/common/port_prober.rb +3 -4
  54. data/lib/selenium/webdriver/common/profile_helper.rb +6 -11
  55. data/lib/selenium/webdriver/common/proxy.rb +58 -72
  56. data/lib/selenium/webdriver/common/search_context.rb +22 -29
  57. data/lib/selenium/webdriver/common/service.rb +161 -0
  58. data/lib/selenium/webdriver/common/socket_lock.rb +6 -14
  59. data/lib/selenium/webdriver/common/socket_poller.rb +5 -12
  60. data/lib/selenium/webdriver/common/target_locator.rb +11 -15
  61. data/lib/selenium/webdriver/common/timeouts.rb +4 -8
  62. data/lib/selenium/webdriver/common/touch_action_builder.rb +2 -6
  63. data/lib/selenium/webdriver/common/touch_screen.rb +19 -23
  64. data/lib/selenium/webdriver/common/w3c_action_builder.rb +209 -0
  65. data/lib/selenium/webdriver/{phantomjs.rb → common/w3c_options.rb} +16 -14
  66. data/lib/selenium/webdriver/common/wait.rb +6 -13
  67. data/lib/selenium/webdriver/common/window.rb +48 -17
  68. data/lib/selenium/webdriver/common/zipper.rb +6 -10
  69. data/lib/selenium/webdriver/edge.rb +5 -12
  70. data/lib/selenium/webdriver/edge/bridge.rb +32 -63
  71. data/lib/selenium/webdriver/edge/driver.rb +73 -0
  72. data/lib/selenium/webdriver/edge/service.rb +18 -87
  73. data/lib/selenium/webdriver/firefox.rb +20 -11
  74. data/lib/selenium/webdriver/firefox/binary.rb +40 -56
  75. data/lib/selenium/webdriver/firefox/driver.rb +48 -0
  76. data/lib/selenium/webdriver/firefox/extension.rb +18 -8
  77. data/lib/selenium/webdriver/firefox/extension/prefs.json +3 -11
  78. data/lib/selenium/webdriver/firefox/extension/webdriver.xpi +0 -0
  79. data/lib/selenium/webdriver/firefox/launcher.rb +13 -22
  80. data/lib/selenium/webdriver/firefox/legacy/driver.rb +79 -0
  81. data/lib/selenium/webdriver/{iphone.rb → firefox/marionette/bridge.rb} +25 -6
  82. data/lib/selenium/webdriver/firefox/marionette/driver.rb +96 -0
  83. data/lib/selenium/webdriver/firefox/options.rb +149 -0
  84. data/lib/selenium/webdriver/firefox/profile.rb +46 -46
  85. data/lib/selenium/webdriver/firefox/profiles_ini.rb +8 -18
  86. data/lib/selenium/webdriver/firefox/service.rb +23 -83
  87. data/lib/selenium/webdriver/firefox/util.rb +0 -4
  88. data/lib/selenium/webdriver/ie.rb +4 -8
  89. data/lib/selenium/webdriver/ie/driver.rb +90 -0
  90. data/lib/selenium/webdriver/ie/options.rb +136 -0
  91. data/lib/selenium/webdriver/ie/service.rb +58 -0
  92. data/lib/selenium/webdriver/remote.rb +8 -16
  93. data/lib/selenium/webdriver/remote/bridge.rb +96 -565
  94. data/lib/selenium/webdriver/remote/capabilities.rb +76 -94
  95. data/lib/selenium/webdriver/remote/driver.rb +49 -0
  96. data/lib/selenium/webdriver/remote/http/common.rb +22 -20
  97. data/lib/selenium/webdriver/remote/http/curb.rb +9 -12
  98. data/lib/selenium/webdriver/remote/http/default.rb +54 -41
  99. data/lib/selenium/webdriver/remote/http/persistent.rb +9 -8
  100. data/lib/selenium/webdriver/remote/oss/bridge.rb +586 -0
  101. data/lib/selenium/webdriver/remote/oss/commands.rb +221 -0
  102. data/lib/selenium/webdriver/remote/response.rb +39 -27
  103. data/lib/selenium/webdriver/remote/server_error.rb +1 -5
  104. data/lib/selenium/webdriver/remote/w3c/bridge.rb +573 -0
  105. data/lib/selenium/webdriver/remote/w3c/capabilities.rb +290 -0
  106. data/lib/selenium/webdriver/remote/w3c/commands.rb +148 -0
  107. data/lib/selenium/webdriver/safari.rb +20 -29
  108. data/lib/selenium/webdriver/{firefox/w3c_bridge.rb → safari/driver.rb} +21 -30
  109. data/lib/selenium/webdriver/safari/service.rb +57 -0
  110. data/lib/selenium/webdriver/support.rb +1 -2
  111. data/lib/selenium/webdriver/support/abstract_event_listener.rb +17 -4
  112. data/lib/selenium/webdriver/support/block_event_listener.rb +1 -5
  113. data/lib/selenium/webdriver/support/color.rb +57 -42
  114. data/lib/selenium/webdriver/support/escaper.rb +41 -0
  115. data/lib/selenium/webdriver/support/event_firing_bridge.rb +36 -40
  116. data/lib/selenium/webdriver/support/select.rb +33 -86
  117. data/selenium-webdriver.gemspec +22 -25
  118. metadata +254 -261
  119. data/lib/selenium-client.rb +0 -21
  120. data/lib/selenium/client.rb +0 -57
  121. data/lib/selenium/client/base.rb +0 -151
  122. data/lib/selenium/client/driver.rb +0 -29
  123. data/lib/selenium/client/errors.rb +0 -28
  124. data/lib/selenium/client/extensions.rb +0 -132
  125. data/lib/selenium/client/idiomatic.rb +0 -507
  126. data/lib/selenium/client/javascript_expression_builder.rb +0 -135
  127. data/lib/selenium/client/javascript_frameworks/jquery.rb +0 -32
  128. data/lib/selenium/client/javascript_frameworks/prototype.rb +0 -32
  129. data/lib/selenium/client/legacy_driver.rb +0 -1722
  130. data/lib/selenium/client/protocol.rb +0 -123
  131. data/lib/selenium/client/selenium_helper.rb +0 -49
  132. data/lib/selenium/rake/server_task.rb +0 -176
  133. data/lib/selenium/webdriver/android/bridge.rb +0 -68
  134. data/lib/selenium/webdriver/chrome/bridge.rb +0 -139
  135. data/lib/selenium/webdriver/common/core_ext/base64.rb +0 -28
  136. data/lib/selenium/webdriver/common/core_ext/dir.rb +0 -61
  137. data/lib/selenium/webdriver/common/html5/location.rb +0 -19
  138. data/lib/selenium/webdriver/common/w3c_error.rb +0 -194
  139. data/lib/selenium/webdriver/edge/legacy_support.rb +0 -117
  140. data/lib/selenium/webdriver/firefox/bridge.rb +0 -89
  141. data/lib/selenium/webdriver/ie/bridge.rb +0 -88
  142. data/lib/selenium/webdriver/ie/server.rb +0 -133
  143. data/lib/selenium/webdriver/iphone/bridge.rb +0 -64
  144. data/lib/selenium/webdriver/phantomjs/bridge.rb +0 -78
  145. data/lib/selenium/webdriver/phantomjs/service.rb +0 -130
  146. data/lib/selenium/webdriver/remote/commands.rb +0 -211
  147. data/lib/selenium/webdriver/remote/w3c_bridge.rb +0 -668
  148. data/lib/selenium/webdriver/remote/w3c_capabilities.rb +0 -236
  149. data/lib/selenium/webdriver/remote/w3c_commands.rb +0 -132
  150. data/lib/selenium/webdriver/safari/bridge.rb +0 -135
  151. data/lib/selenium/webdriver/safari/resources/client.js +0 -7255
  152. data/lib/selenium/webdriver/safari/server.rb +0 -187
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
- #
3
1
  # Licensed to the Software Freedom Conservancy (SFC) under one
4
2
  # or more contributor license agreements. See the NOTICE file
5
3
  # distributed with this work for additional information
@@ -20,13 +18,12 @@
20
18
  module Selenium
21
19
  module WebDriver
22
20
  module Firefox
23
-
24
21
  #
25
22
  # @api private
26
23
  #
27
24
 
28
25
  class Extension
29
- NAMESPACE = 'http://www.mozilla.org/2004/em-rdf#'
26
+ NAMESPACE = 'http://www.mozilla.org/2004/em-rdf#'.freeze
30
27
 
31
28
  def initialize(path)
32
29
  unless File.exist?(path)
@@ -39,10 +36,10 @@ module Selenium
39
36
 
40
37
  def write_to(extensions_dir)
41
38
  root_dir = create_root
42
- ext_path = File.join extensions_dir, read_id_from_install_rdf(root_dir)
39
+ ext_path = File.join extensions_dir, read_id(root_dir)
43
40
 
44
41
  FileUtils.rm_rf ext_path
45
- FileUtils.mkdir_p File.dirname(ext_path), :mode => 0700
42
+ FileUtils.mkdir_p File.dirname(ext_path), mode: 0o700
46
43
  FileUtils.cp_r root_dir, ext_path
47
44
 
48
45
  FileReaper.reap(root_dir) if @should_reap_root
@@ -55,7 +52,7 @@ module Selenium
55
52
  @path
56
53
  else
57
54
  unless Zipper::EXTENSIONS.include? File.extname(@path)
58
- raise Error::WebDriverError, "expected #{Zipper::EXTENSIONS.join(" or ")}, got #{@path.inspect}"
55
+ raise Error::WebDriverError, "expected #{Zipper::EXTENSIONS.join(' or ')}, got #{@path.inspect}"
59
56
  end
60
57
 
61
58
  @should_reap_root = true
@@ -63,8 +60,14 @@ module Selenium
63
60
  end
64
61
  end
65
62
 
63
+ def read_id(directory)
64
+ read_id_from_install_rdf(directory) || read_id_from_manifest_json(directory)
65
+ end
66
+
66
67
  def read_id_from_install_rdf(directory)
67
- rdf_path = File.join(directory, "install.rdf")
68
+ rdf_path = File.join(directory, 'install.rdf')
69
+ return unless File.exist?(rdf_path)
70
+
68
71
  doc = REXML::Document.new(File.read(rdf_path))
69
72
  namespace = doc.root.namespaces.key(NAMESPACE)
70
73
 
@@ -79,6 +82,13 @@ module Selenium
79
82
  raise Error::WebDriverError, "cannot locate extension id in #{rdf_path}"
80
83
  end
81
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
82
92
  end # Extension
83
93
  end # Firefox
84
94
  end # WebDriver
@@ -37,18 +37,8 @@
37
37
  "network.http.phishy-userpass-length": 255,
38
38
  "offline-apps.allow_by_default": true,
39
39
  "prompts.tab_modal.enabled": false,
40
- "security.csp.enable": false,
41
40
  "security.fileuri.origin_policy": 3,
42
41
  "security.fileuri.strict_origin_policy": false,
43
- "security.warn_entering_secure": false,
44
- "security.warn_entering_secure.show_once": false,
45
- "security.warn_entering_weak": false,
46
- "security.warn_entering_weak.show_once": false,
47
- "security.warn_leaving_secure": false,
48
- "security.warn_leaving_secure.show_once": false,
49
- "security.warn_submit_insecure": false,
50
- "security.warn_viewing_mixed": false,
51
- "security.warn_viewing_mixed.show_once": false,
52
42
  "signon.rememberSignons": false,
53
43
  "toolkit.networkmanager.disable": true,
54
44
  "toolkit.telemetry.prompted": 2,
@@ -64,12 +54,14 @@
64
54
  "browser.newtabpage.enabled": false,
65
55
  "browser.startup.page": 0,
66
56
  "browser.startup.homepage": "about:blank",
57
+ "browser.startup.homepage_override.mstone": "ignore",
67
58
  "browser.usedOnWindows10.introURL": "about:blank",
68
59
  "dom.max_chrome_script_run_time": 30,
69
60
  "dom.max_script_run_time": 30,
70
61
  "dom.report_all_js_exceptions": true,
71
62
  "javascript.options.showInConsole": true,
72
- "network.http.max-connections-per-server": 10,
63
+ "network.captive-portal-service.enabled": false,
64
+ "security.csp.enable": false,
73
65
  "startup.homepage_welcome_url": "about:blank",
74
66
  "startup.homepage_welcome_url.additional": "about:blank",
75
67
  "webdriver_accept_untrusted_certs": true,
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
- #
3
1
  # Licensed to the Software Freedom Conservancy (SFC) under one
4
2
  # or more contributor license agreements. See the NOTICE file
5
3
  # distributed with this work for additional information
@@ -20,10 +18,8 @@
20
18
  module Selenium
21
19
  module WebDriver
22
20
  module Firefox
23
-
24
21
  # @api private
25
22
  class Launcher
26
-
27
23
  SOCKET_LOCK_TIMEOUT = 45
28
24
  STABLE_CONNECTION_TIMEOUT = 60
29
25
 
@@ -33,14 +29,14 @@ module Selenium
33
29
 
34
30
  raise Error::WebDriverError, "invalid port: #{@port}" if @port < 1
35
31
 
36
- if profile.kind_of? Profile
32
+ if profile.is_a? Profile
37
33
  @profile = profile
38
34
  else
39
35
  @profile_name = profile
40
36
  @profile = nil
41
37
  end
42
38
 
43
- @host = "127.0.0.1"
39
+ @host = '127.0.0.1'
44
40
  end
45
41
 
46
42
  def url
@@ -79,38 +75,33 @@ module Selenium
79
75
 
80
76
  def start
81
77
  assert_profile
82
- @binary.start_with @profile, @profile_dir, "-foreground"
78
+ @binary.start_with @profile, @profile_dir, '-foreground'
83
79
  end
84
80
 
85
81
  def connect_until_stable
86
82
  poller = SocketPoller.new(@host, @port, STABLE_CONNECTION_TIMEOUT)
87
83
 
88
- unless poller.connected?
89
- @binary.quit
90
- raise Error::WebDriverError, "unable to obtain stable firefox connection in #{STABLE_CONNECTION_TIMEOUT} seconds (#{@host}:#{@port})"
91
- end
84
+ return if poller.connected?
85
+ @binary.quit
86
+ error = "unable to obtain stable firefox connection in #{STABLE_CONNECTION_TIMEOUT} seconds (#{@host}:#{@port})"
87
+ raise Error::WebDriverError, error
92
88
  end
93
89
 
94
90
  def fetch_profile
95
- if @profile_name
96
- @profile = Profile.from_name @profile_name
97
-
98
- unless @profile
99
- raise Error::WebDriverError, "unable to find profile named: #{@profile_name.inspect}"
100
- end
101
- else
102
- @profile = Profile.new
103
- end
91
+ @profile = if @profile_name
92
+ Profile.from_name @profile_name
93
+ else
94
+ Profile.new
95
+ end
104
96
  end
105
97
 
106
98
  def assert_profile
107
- raise Error::WebDriverError, "must create_profile first" unless @profile && @profile_dir
99
+ raise Error::WebDriverError, 'must create_profile first' unless @profile && @profile_dir
108
100
  end
109
101
 
110
102
  def socket_lock
111
103
  @socket_lock ||= SocketLock.new(@port - 1, SOCKET_LOCK_TIMEOUT)
112
104
  end
113
-
114
105
  end # Launcher
115
106
  end # Firefox
116
107
  end # WebDriver
@@ -0,0 +1,79 @@
1
+ # Licensed to the Software Freedom Conservancy (SFC) under one
2
+ # or more contributor license agreements. See the NOTICE file
3
+ # distributed with this work for additional information
4
+ # regarding copyright ownership. The SFC licenses this file
5
+ # to you under the Apache License, Version 2.0 (the
6
+ # "License"); you may not use this file except in compliance
7
+ # with the License. You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing,
12
+ # software distributed under the License is distributed on an
13
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ # KIND, either express or implied. See the License for the
15
+ # specific language governing permissions and limitations
16
+ # under the License.
17
+
18
+ module Selenium
19
+ module WebDriver
20
+ module Firefox
21
+ module Legacy
22
+
23
+ #
24
+ # Driver implementation for Firefox using legacy extension.
25
+ # @api private
26
+ #
27
+
28
+ class Driver < WebDriver::Driver
29
+ include DriverExtensions::TakesScreenshot
30
+
31
+ def initialize(opts = {})
32
+ opts[:desired_capabilities] ||= Remote::Capabilities.firefox
33
+
34
+ if opts.key? :proxy
35
+ WebDriver.logger.deprecate ':proxy', "Selenium::WebDriver::Remote::Capabilities.firefox(proxy: #{opts[:proxy]})"
36
+ opts[:desired_capabilities].proxy = opts.delete(:proxy)
37
+ end
38
+
39
+ unless opts.key?(:url)
40
+ port = opts.delete(:port) || DEFAULT_PORT
41
+ profile = opts.delete(:profile)
42
+
43
+ Binary.path = opts[:desired_capabilities][:firefox_binary] if opts[:desired_capabilities][:firefox_binary]
44
+ @launcher = Launcher.new Binary.new, port, profile
45
+ @launcher.launch
46
+ opts[:url] = @launcher.url
47
+ end
48
+
49
+ listener = opts.delete(:listener)
50
+ WebDriver.logger.info 'Skipping handshake as we know it is OSS.'
51
+ desired_capabilities = opts.delete(:desired_capabilities)
52
+ bridge = Remote::Bridge.new(opts)
53
+ capabilities = bridge.create_session(desired_capabilities)
54
+ @bridge = Remote::OSS::Bridge.new(capabilities, bridge.session_id, opts)
55
+
56
+ begin
57
+ super(@bridge, listener: listener)
58
+ rescue
59
+ @launcher.quit if @launcher
60
+ raise
61
+ end
62
+ end
63
+
64
+ def browser
65
+ :firefox
66
+ end
67
+
68
+ def quit
69
+ super
70
+ nil
71
+ ensure
72
+ @launcher.quit
73
+ end
74
+
75
+ end # Driver
76
+ end # Legacy
77
+ end # Firefox
78
+ end # WebDriver
79
+ end # Selenium
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
- #
3
1
  # Licensed to the Software Freedom Conservancy (SFC) under one
4
2
  # or more contributor license agreements. See the NOTICE file
5
3
  # distributed with this work for additional information
@@ -19,10 +17,31 @@
19
17
 
20
18
  module Selenium
21
19
  module WebDriver
22
- module IPhone
20
+ module Firefox
21
+ module Marionette
22
+ module Bridge
23
+
24
+ COMMANDS = {
25
+ install_addon: [:post, 'session/:session_id/moz/addon/install'.freeze],
26
+ uninstall_addon: [:post, 'session/:session_id/moz/addon/uninstall'.freeze]
27
+ }.freeze
28
+
29
+ def commands(command)
30
+ COMMANDS[command] || super
31
+ end
23
32
 
24
- end # IPhone
33
+ def install_addon(path, temporary)
34
+ payload = {path: path}
35
+ payload[:temporary] = temporary unless temporary.nil?
36
+ execute :install_addon, {}, payload
37
+ end
38
+
39
+ def uninstall_addon(id)
40
+ execute :uninstall_addon, {}, {id: id}
41
+ end
42
+
43
+ end # Bridge
44
+ end # Marionette
45
+ end # Firefox
25
46
  end # WebDriver
26
47
  end # Selenium
27
-
28
- require 'selenium/webdriver/iphone/bridge'
@@ -0,0 +1,96 @@
1
+ # Licensed to the Software Freedom Conservancy (SFC) under one
2
+ # or more contributor license agreements. See the NOTICE file
3
+ # distributed with this work for additional information
4
+ # regarding copyright ownership. The SFC licenses this file
5
+ # to you under the Apache License, Version 2.0 (the
6
+ # "License"); you may not use this file except in compliance
7
+ # with the License. You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing,
12
+ # software distributed under the License is distributed on an
13
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ # KIND, either express or implied. See the License for the
15
+ # specific language governing permissions and limitations
16
+ # under the License.
17
+
18
+ module Selenium
19
+ module WebDriver
20
+ module Firefox
21
+ module Marionette
22
+
23
+ #
24
+ # Driver implementation for Firefox using GeckoDriver.
25
+ # @api private
26
+ #
27
+
28
+ class Driver < WebDriver::Driver
29
+ include DriverExtensions::HasAddons
30
+ include DriverExtensions::HasWebStorage
31
+ include DriverExtensions::TakesScreenshot
32
+
33
+ def initialize(opts = {})
34
+ opts[:desired_capabilities] = create_capabilities(opts)
35
+
36
+ unless opts.key?(:url)
37
+ driver_path = opts.delete(:driver_path) || Firefox.driver_path
38
+ driver_opts = opts.delete(:driver_opts) || {}
39
+ port = opts.delete(:port) || Service::DEFAULT_PORT
40
+
41
+ @service = Service.new(driver_path, port, driver_opts)
42
+ @service.start
43
+ opts[:url] = @service.uri
44
+ end
45
+
46
+ listener = opts.delete(:listener)
47
+ WebDriver.logger.info 'Skipping handshake as we know it is W3C.'
48
+ desired_capabilities = opts.delete(:desired_capabilities)
49
+ bridge = Remote::Bridge.new(opts)
50
+ capabilities = bridge.create_session(desired_capabilities)
51
+ @bridge = Remote::W3C::Bridge.new(capabilities, bridge.session_id, opts)
52
+ @bridge.extend Marionette::Bridge
53
+
54
+ super(@bridge, listener: listener)
55
+ end
56
+
57
+ def browser
58
+ :firefox
59
+ end
60
+
61
+ def quit
62
+ super
63
+ ensure
64
+ @service.stop if @service
65
+ end
66
+
67
+ private
68
+
69
+ def create_capabilities(opts)
70
+ caps = opts.delete(:desired_capabilities) { Remote::W3C::Capabilities.firefox }
71
+ options = opts.delete(:options) { Options.new }
72
+
73
+ firefox_options = opts.delete(:firefox_options)
74
+ if firefox_options
75
+ WebDriver.logger.deprecate ':firefox_options', 'Selenium::WebDriver::Firefox::Options'
76
+ firefox_options.each do |key, value|
77
+ options.add_option(key, value)
78
+ end
79
+ end
80
+
81
+ profile = opts.delete(:profile)
82
+ if profile
83
+ WebDriver.logger.deprecate ':profile', 'Selenium::WebDriver::Firefox::Options#profile='
84
+ options.profile = profile
85
+ end
86
+
87
+ options = options.as_json
88
+ caps.merge!(options) unless options.empty?
89
+
90
+ caps
91
+ end
92
+ end # Driver
93
+ end # Marionette
94
+ end # Firefox
95
+ end # WebDriver
96
+ end # Selenium
@@ -0,0 +1,149 @@
1
+ # Licensed to the Software Freedom Conservancy (SFC) under one
2
+ # or more contributor license agreements. See the NOTICE file
3
+ # distributed with this work for additional information
4
+ # regarding copyright ownership. The SFC licenses this file
5
+ # to you under the Apache License, Version 2.0 (the
6
+ # "License"); you may not use this file except in compliance
7
+ # with the License. You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing,
12
+ # software distributed under the License is distributed on an
13
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
+ # KIND, either express or implied. See the License for the
15
+ # specific language governing permissions and limitations
16
+ # under the License.
17
+
18
+ module Selenium
19
+ module WebDriver
20
+ module Firefox
21
+ class Options
22
+ attr_reader :args, :prefs, :options, :profile
23
+ attr_accessor :binary, :log_level
24
+
25
+ KEY = 'moz:firefoxOptions'.freeze
26
+
27
+ #
28
+ # Create a new Options instance, only for W3C-capable versions of Firefox.
29
+ #
30
+ # @example
31
+ # options = Selenium::WebDriver::Firefox::Options.new(args: ['--host=127.0.0.1'])
32
+ # driver = Selenium::WebDriver.for :firefox, options: options
33
+ #
34
+ # @param [Hash] opts the pre-defined options to create the Firefox::Options with
35
+ # @option opts [String] :binary Path to the Firefox executable to use
36
+ # @option opts [Array<String>] :args List of command-line arguments to use when starting geckodriver
37
+ # @option opts [Profile, String] :profile Encoded profile string or Profile instance
38
+ # @option opts [String, Symbol] :log_level Log level for geckodriver
39
+ # @option opts [Hash] :prefs A hash with each entry consisting of the key of the preference and its value
40
+ # @option opts [Hash] :options A hash for raw options
41
+ #
42
+
43
+ def initialize(**opts)
44
+ @args = opts.delete(:args) || []
45
+ @binary = opts.delete(:binary)
46
+ @profile = opts.delete(:profile)
47
+ @log_level = opts.delete(:log_level)
48
+ @prefs = opts.delete(:prefs) || {}
49
+ @options = opts.delete(:options) || {}
50
+ end
51
+
52
+ #
53
+ # Add a command-line argument to use when starting Firefox.
54
+ #
55
+ # @example Start geckodriver on a specific host
56
+ # options = Selenium::WebDriver::Firefox::Options.new
57
+ # options.add_argument('--host=127.0.0.1')
58
+ #
59
+ # @param [String] arg The command-line argument to add
60
+ #
61
+
62
+ def add_argument(arg)
63
+ @args << arg
64
+ end
65
+
66
+ #
67
+ # Add a new option not yet handled by these bindings.
68
+ #
69
+ # @example
70
+ # options = Selenium::WebDriver::Firefox::Options.new
71
+ # options.add_option(:foo, 'bar')
72
+ #
73
+ # @param [String, Symbol] name Name of the option
74
+ # @param [Boolean, String, Integer] value Value of the option
75
+ #
76
+
77
+ def add_option(name, value)
78
+ @options[name] = value
79
+ end
80
+
81
+ #
82
+ # Add a preference that is only applied to the user profile in use.
83
+ #
84
+ # @example Set the default homepage
85
+ # options = Selenium::WebDriver::Firefox::Options.new
86
+ # options.add_preference('browser.startup.homepage', 'http://www.seleniumhq.com/')
87
+ #
88
+ # @param [String] name Key of the preference
89
+ # @param [Boolean, String, Integer] value Value of the preference
90
+ #
91
+
92
+ def add_preference(name, value)
93
+ prefs[name] = value
94
+ end
95
+
96
+ #
97
+ # Run Firefox in headless mode.
98
+ #
99
+ # @example Enable headless mode
100
+ # options = Selenium::WebDriver::Firefox::Options.new
101
+ # options.headless!
102
+ #
103
+
104
+ def headless!
105
+ add_argument '-headless'
106
+ end
107
+
108
+ #
109
+ # Sets Firefox profile.
110
+ #
111
+ # @example Set the custom profile
112
+ # profile = Selenium::WebDriver::Firefox::Profile.new
113
+ # options = Selenium::WebDriver::Firefox::Options.new
114
+ # options.profile = profile
115
+ #
116
+ # @example Use existing profile
117
+ # options = Selenium::WebDriver::Firefox::Options.new
118
+ # options.profile = 'myprofile'
119
+ #
120
+ # @param [Profile, String] profile Profile to be used
121
+ #
122
+
123
+ def profile=(profile)
124
+ @profile = if profile.is_a?(Profile)
125
+ profile
126
+ else
127
+ Profile.from_name(profile)
128
+ end
129
+ end
130
+
131
+ #
132
+ # @api private
133
+ #
134
+
135
+ def as_json(*)
136
+ opts = @options
137
+
138
+ opts[:profile] = @profile.encoded if @profile
139
+ opts[:args] = @args if @args.any?
140
+ opts[:binary] = @binary if @binary
141
+ opts[:prefs] = @prefs unless @prefs.empty?
142
+ opts[:log] = {level: @log_level} if @log_level
143
+
144
+ {KEY => opts}
145
+ end
146
+ end # Options
147
+ end # Firefox
148
+ end # WebDriver
149
+ end # Selenium