selenium-webdriver 2.53.4 → 3.8.0

Sign up to get free protection for your applications and to get access to all the features.
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