selenium-webdriver 4.0.0.alpha2 → 4.0.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 (113) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGES +338 -4
  3. data/Gemfile +3 -1
  4. data/LICENSE +1 -1
  5. data/NOTICE +2 -0
  6. data/README.md +4 -5
  7. data/lib/selenium/server.rb +21 -29
  8. data/lib/selenium/webdriver/atoms/findElements.js +122 -0
  9. data/lib/selenium/webdriver/atoms/getAttribute.js +100 -7
  10. data/lib/selenium/webdriver/atoms/isDisplayed.js +76 -78
  11. data/lib/selenium/webdriver/atoms/mutationListener.js +55 -0
  12. data/lib/selenium/webdriver/chrome/driver.rb +26 -56
  13. data/lib/selenium/webdriver/chrome/features.rb +106 -0
  14. data/lib/selenium/webdriver/chrome/options.rb +127 -52
  15. data/lib/selenium/webdriver/chrome/profile.rb +8 -5
  16. data/lib/selenium/webdriver/chrome/service.rb +4 -6
  17. data/lib/selenium/webdriver/chrome.rb +10 -9
  18. data/lib/selenium/webdriver/common/driver.rb +110 -19
  19. data/lib/selenium/webdriver/common/driver_extensions/full_page_screenshot.rb +43 -0
  20. data/lib/selenium/webdriver/common/driver_extensions/has_apple_permissions.rb +51 -0
  21. data/lib/selenium/webdriver/common/driver_extensions/has_authentication.rb +89 -0
  22. data/lib/selenium/webdriver/common/driver_extensions/has_casting.rb +77 -0
  23. data/lib/selenium/webdriver/common/driver_extensions/has_cdp.rb +38 -0
  24. data/lib/selenium/webdriver/common/driver_extensions/has_context.rb +45 -0
  25. data/lib/selenium/webdriver/common/driver_extensions/has_devtools.rb +43 -0
  26. data/lib/selenium/webdriver/common/driver_extensions/has_launching.rb +38 -0
  27. data/lib/selenium/webdriver/common/driver_extensions/has_location.rb +5 -8
  28. data/lib/selenium/webdriver/common/driver_extensions/has_log_events.rb +144 -0
  29. data/lib/selenium/webdriver/common/driver_extensions/has_logs.rb +30 -0
  30. data/lib/selenium/webdriver/common/driver_extensions/has_network_conditions.rb +17 -0
  31. data/lib/selenium/webdriver/common/driver_extensions/has_network_connection.rb +6 -27
  32. data/lib/selenium/webdriver/common/driver_extensions/has_network_interception.rb +136 -0
  33. data/lib/selenium/webdriver/common/driver_extensions/has_permissions.rb +11 -11
  34. data/lib/selenium/webdriver/common/driver_extensions/has_pinned_scripts.rb +77 -0
  35. data/lib/selenium/webdriver/common/driver_extensions/has_remote_status.rb +1 -0
  36. data/lib/selenium/webdriver/common/driver_extensions/{rotatable.rb → prints_page.rb} +18 -20
  37. data/lib/selenium/webdriver/common/element.rb +79 -16
  38. data/lib/selenium/webdriver/common/error.rb +12 -0
  39. data/lib/selenium/webdriver/common/interactions/interaction.rb +4 -1
  40. data/lib/selenium/webdriver/common/log_entry.rb +2 -2
  41. data/lib/selenium/webdriver/common/logger.rb +50 -15
  42. data/lib/selenium/webdriver/common/manager.rb +14 -14
  43. data/lib/selenium/webdriver/common/options.rb +186 -0
  44. data/lib/selenium/webdriver/common/platform.rb +6 -1
  45. data/lib/selenium/webdriver/common/port_prober.rb +4 -6
  46. data/lib/selenium/webdriver/common/profile_helper.rb +10 -2
  47. data/lib/selenium/webdriver/common/proxy.rb +6 -3
  48. data/lib/selenium/webdriver/common/search_context.rb +7 -3
  49. data/lib/selenium/webdriver/common/service.rb +23 -113
  50. data/lib/selenium/webdriver/common/service_manager.rb +151 -0
  51. data/lib/selenium/webdriver/common/shadow_root.rb +87 -0
  52. data/lib/selenium/webdriver/common/socket_lock.rb +2 -2
  53. data/lib/selenium/webdriver/common/takes_screenshot.rb +66 -0
  54. data/lib/selenium/webdriver/common/target_locator.rb +32 -4
  55. data/lib/selenium/webdriver/common/timeouts.rb +31 -4
  56. data/lib/selenium/webdriver/common/wait.rb +1 -1
  57. data/lib/selenium/webdriver/common/window.rb +0 -4
  58. data/lib/selenium/webdriver/common.rb +17 -2
  59. data/lib/selenium/webdriver/devtools/console_event.rb +38 -0
  60. data/lib/selenium/webdriver/devtools/exception_event.rb +36 -0
  61. data/lib/selenium/webdriver/devtools/mutation_event.rb +37 -0
  62. data/lib/selenium/webdriver/{chrome/bridge.rb → devtools/pinned_script.rb} +26 -17
  63. data/lib/selenium/webdriver/devtools/request.rb +67 -0
  64. data/lib/selenium/webdriver/devtools/response.rb +66 -0
  65. data/lib/selenium/webdriver/devtools.rb +182 -0
  66. data/lib/selenium/webdriver/edge/driver.rb +5 -31
  67. data/lib/selenium/webdriver/edge/features.rb +44 -0
  68. data/lib/selenium/webdriver/edge/options.rb +11 -48
  69. data/lib/selenium/webdriver/edge/profile.rb +33 -0
  70. data/lib/selenium/webdriver/edge/service.rb +9 -24
  71. data/lib/selenium/webdriver/edge.rb +11 -13
  72. data/lib/selenium/webdriver/firefox/driver.rb +20 -30
  73. data/lib/selenium/webdriver/firefox/extension.rb +8 -0
  74. data/lib/selenium/webdriver/firefox/{bridge.rb → features.rb} +23 -4
  75. data/lib/selenium/webdriver/firefox/options.rb +70 -49
  76. data/lib/selenium/webdriver/firefox/profile.rb +16 -77
  77. data/lib/selenium/webdriver/firefox/service.rb +1 -5
  78. data/lib/selenium/webdriver/firefox.rb +22 -16
  79. data/lib/selenium/webdriver/ie/driver.rb +1 -34
  80. data/lib/selenium/webdriver/ie/options.rb +13 -44
  81. data/lib/selenium/webdriver/ie/service.rb +9 -11
  82. data/lib/selenium/webdriver/ie.rb +8 -7
  83. data/lib/selenium/webdriver/remote/bridge.rb +112 -86
  84. data/lib/selenium/webdriver/remote/capabilities.rb +120 -62
  85. data/lib/selenium/webdriver/remote/commands.rb +7 -0
  86. data/lib/selenium/webdriver/remote/driver.rb +15 -12
  87. data/lib/selenium/webdriver/remote/http/common.rb +0 -5
  88. data/lib/selenium/webdriver/remote/http/default.rb +17 -11
  89. data/lib/selenium/webdriver/remote/http/persistent.rb +11 -6
  90. data/lib/selenium/webdriver/remote.rb +15 -9
  91. data/lib/selenium/webdriver/safari/driver.rb +3 -34
  92. data/lib/selenium/webdriver/safari/{bridge.rb → features.rb} +6 -6
  93. data/lib/selenium/webdriver/safari/options.rb +10 -29
  94. data/lib/selenium/webdriver/safari/service.rb +0 -4
  95. data/lib/selenium/webdriver/safari.rb +16 -8
  96. data/lib/selenium/webdriver/support/block_event_listener.rb +1 -1
  97. data/lib/selenium/webdriver/support/cdp/domain.rb.erb +63 -0
  98. data/lib/selenium/webdriver/support/cdp_client_generator.rb +108 -0
  99. data/lib/selenium/webdriver/support/color.rb +2 -2
  100. data/lib/selenium/webdriver/support/event_firing_bridge.rb +4 -4
  101. data/lib/selenium/webdriver/support/guards/guard.rb +89 -0
  102. data/lib/selenium/webdriver/support/guards/guard_condition.rb +52 -0
  103. data/lib/selenium/webdriver/support/guards.rb +95 -0
  104. data/lib/selenium/webdriver/support/relative_locator.rb +51 -0
  105. data/lib/selenium/webdriver/support/select.rb +2 -2
  106. data/lib/selenium/webdriver/support.rb +1 -0
  107. data/lib/selenium/webdriver/version.rb +1 -1
  108. data/lib/selenium/webdriver.rb +10 -8
  109. data/selenium-webdriver.gemspec +29 -13
  110. metadata +125 -51
  111. data/lib/selenium/webdriver/common/driver_extensions/takes_screenshot.rb +0 -64
  112. data/lib/selenium/webdriver/firefox/binary.rb +0 -110
  113. data/lib/selenium/webdriver/firefox/extension/prefs.json +0 -69
@@ -17,62 +17,25 @@
17
17
  # specific language governing permissions and limitations
18
18
  # under the License.
19
19
 
20
+ require 'selenium/webdriver/chrome/options'
21
+
20
22
  module Selenium
21
23
  module WebDriver
22
24
  module Edge
23
- class Options
24
- attr_accessor :in_private, :start_page
25
- attr_reader :extension_paths
25
+ class Options < Selenium::WebDriver::Chrome::Options
26
+ KEY = 'ms:edgeOptions'
27
+ BROWSER = 'MicrosoftEdge'
26
28
 
27
- #
28
- # Create a new Options instance for Edge.
29
- #
30
- # @example
31
- # options = Selenium::WebDriver::Edge::Options.new(in_private: true)
32
- # driver = Selenium::WebDriver.for :edge, options: options
33
- #
34
- # @param [Hash] opts the pre-defined options to create the Edge::Options with
35
- # @option opts [Boolean] :in_private Start in private mode. Default is false
36
- # @option opts [Array<String>] :extension_paths A list of full paths to extensions to install on startup
37
- # @option opts [String] :start_page Default page to start with
38
- #
39
- # @see https://docs.microsoft.com/en-us/microsoft-edge/webdriver
40
- #
29
+ protected
41
30
 
42
- def initialize(**opts)
43
- @in_private = opts.delete(:in_private) || false
44
- @extension_paths = opts.delete(:extension_paths) || []
45
- @start_page = opts.delete(:start_page)
31
+ def enable_logging(browser_options)
32
+ browser_options['ms:loggingPrefs'] = @logging_prefs
46
33
  end
47
34
 
48
- #
49
- # Add an extension by local path.
50
- #
51
- # @example
52
- # options = Selenium::WebDriver::Edge::Options.new
53
- # options.add_extension_path('C:\path\to\extension')
54
- #
55
- # @param [String] path The local path to the extension folder
56
- #
57
-
58
- def add_extension_path(path)
59
- raise Error::WebDriverError, "could not find extension at #{path.inspect}" unless File.directory?(path)
60
-
61
- @extension_paths << path
62
- end
63
-
64
- #
65
- # @api private
66
- #
67
-
68
- def as_json(*)
69
- opts = {}
70
-
71
- opts['ms:inPrivate'] = true if @in_private
72
- opts['ms:extensionPaths'] = @extension_paths if @extension_paths.any?
73
- opts['ms:startPage'] = @start_page if @start_page
35
+ private
74
36
 
75
- opts
37
+ def binary_path
38
+ Edge.path
76
39
  end
77
40
  end # Options
78
41
  end # Edge
@@ -0,0 +1,33 @@
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
+ require 'selenium/webdriver/chrome/profile'
21
+
22
+ module Selenium
23
+ module WebDriver
24
+ module Edge
25
+ #
26
+ # @private
27
+ #
28
+
29
+ class Profile < Selenium::WebDriver::Chrome::Profile
30
+ end # Profile
31
+ end # Edge
32
+ end # WebDriver
33
+ end # Selenium
@@ -17,35 +17,20 @@
17
17
  # specific language governing permissions and limitations
18
18
  # under the License.
19
19
 
20
+ require 'selenium/webdriver/chrome/service'
21
+
20
22
  module Selenium
21
23
  module WebDriver
22
24
  module Edge
23
- #
24
- # @api private
25
- #
26
-
27
- class Service < WebDriver::Service
28
- DEFAULT_PORT = 17556
29
- EXECUTABLE = 'MicrosoftWebDriver'
25
+ class Service < Selenium::WebDriver::Chrome::Service
26
+ DEFAULT_PORT = 9515
27
+ EXECUTABLE = 'msedgedriver'
30
28
  MISSING_TEXT = <<~ERROR
31
- Unable to find MicrosoftWebDriver. Please install it following instructions
32
- at https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/.
29
+ Unable to find msedgedriver. Please download the server from
30
+ https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/ and place it somewhere on your PATH.
33
31
  ERROR
34
- SHUTDOWN_SUPPORTED = false
35
-
36
- private
37
-
38
- # Note: This processing is deprecated
39
- def extract_service_args(driver_opts)
40
- driver_args = super
41
- driver_opts = driver_opts.dup
42
- driver_args << "--host=#{driver_opts[:host]}" if driver_opts.key? :host
43
- driver_args << "--package=#{driver_opts[:package]}" if driver_opts.key? :package
44
- driver_args << "--silent" if driver_opts[:silent] == true
45
- driver_args << "--verbose" if driver_opts[:verbose] == true
46
- driver_args
47
- end
32
+ SHUTDOWN_SUPPORTED = true
48
33
  end # Service
49
34
  end # Edge
50
35
  end # WebDriver
51
- end # Service
36
+ end # Selenium
@@ -19,25 +19,23 @@
19
19
 
20
20
  require 'net/http'
21
21
 
22
- require 'selenium/webdriver/edge/driver'
23
- require 'selenium/webdriver/edge/options'
24
-
25
22
  module Selenium
26
23
  module WebDriver
27
24
  module Edge
28
- def self.driver_path=(path)
29
- WebDriver.logger.deprecate 'Selenium::WebDriver::Edge#driver_path=',
30
- 'Selenium::WebDriver::Edge::Service#driver_path='
31
- Selenium::WebDriver::Edge::Service.driver_path = path
25
+ autoload :Features, 'selenium/webdriver/edge/features'
26
+ autoload :Driver, 'selenium/webdriver/edge/driver'
27
+ autoload :Profile, 'selenium/webdriver/edge/profile'
28
+ autoload :Options, 'selenium/webdriver/edge/options'
29
+ autoload :Service, 'selenium/webdriver/edge/service'
30
+
31
+ def self.path=(path)
32
+ Platform.assert_executable path
33
+ @path = path
32
34
  end
33
35
 
34
- def self.driver_path
35
- WebDriver.logger.deprecate 'Selenium::WebDriver::Edge#driver_path',
36
- 'Selenium::WebDriver::Edge::Service#driver_path'
37
- Selenium::WebDriver::Edge::Service.driver_path
36
+ def self.path
37
+ @path ||= nil
38
38
  end
39
39
  end # Edge
40
40
  end # WebDriver
41
41
  end # Selenium
42
-
43
- require 'selenium/webdriver/edge/service'
@@ -27,44 +27,34 @@ module Selenium
27
27
  #
28
28
 
29
29
  class Driver < WebDriver::Driver
30
- include DriverExtensions::HasAddons
31
- include DriverExtensions::HasWebStorage
32
- include DriverExtensions::TakesScreenshot
33
-
34
- def initialize(opts = {})
35
- opts[:desired_capabilities] = create_capabilities(opts)
36
-
37
- opts[:url] ||= service_url(opts)
38
-
39
- listener = opts.delete(:listener)
40
- desired_capabilities = opts.delete(:desired_capabilities)
41
-
42
- @bridge = Remote::Bridge.new(opts)
43
- @bridge.extend Bridge
44
- @bridge.create_session(desired_capabilities)
45
-
46
- super(@bridge, listener: listener)
47
- end
30
+ EXTENSIONS = [DriverExtensions::HasAddons,
31
+ DriverExtensions::FullPageScreenshot,
32
+ DriverExtensions::HasContext,
33
+ DriverExtensions::HasDevTools,
34
+ DriverExtensions::HasLogEvents,
35
+ DriverExtensions::HasNetworkInterception,
36
+ DriverExtensions::HasWebStorage,
37
+ DriverExtensions::PrintsPage].freeze
48
38
 
49
39
  def browser
50
40
  :firefox
51
41
  end
52
42
 
53
- def quit
54
- super
55
- ensure
56
- @service&.stop
57
- end
58
-
59
43
  private
60
44
 
61
- def create_capabilities(opts)
62
- caps = opts.delete(:desired_capabilities) { Remote::Capabilities.firefox }
63
- options = opts.delete(:options) { Options.new }
64
- options = options.as_json
65
- caps.merge!(options) unless options.empty?
45
+ def devtools_url
46
+ if capabilities['moz:debuggerAddress'].nil?
47
+ raise(Error::WebDriverError, "DevTools is not supported by this version of Firefox; use v85 or higher")
48
+ end
49
+
50
+ uri = URI("http://#{capabilities['moz:debuggerAddress']}")
51
+ response = Net::HTTP.get(uri.hostname, '/json/version', uri.port)
52
+
53
+ JSON.parse(response)['webSocketDebuggerUrl']
54
+ end
66
55
 
67
- caps
56
+ def devtools_version
57
+ Firefox::DEVTOOLS_VERSION
68
58
  end
69
59
  end # Driver
70
60
  end # Firefox
@@ -87,6 +87,14 @@ module Selenium
87
87
  return unless File.exist?(manifest_path)
88
88
 
89
89
  manifest = JSON.parse(File.read(manifest_path))
90
+ applications_gecko_id(manifest) || name_and_version(manifest)
91
+ end
92
+
93
+ def applications_gecko_id(manifest)
94
+ manifest.dig('applications', 'gecko', 'id')&.strip
95
+ end
96
+
97
+ def name_and_version(manifest)
90
98
  [manifest['name'].delete(' '), manifest['version']].join('@')
91
99
  end
92
100
  end # Extension
@@ -20,18 +20,26 @@
20
20
  module Selenium
21
21
  module WebDriver
22
22
  module Firefox
23
- module Bridge
23
+ module Features
24
24
 
25
- COMMANDS = {
25
+ FIREFOX_COMMANDS = {
26
+ get_context: [:get, 'session/:session_id/moz/context'],
27
+ set_context: [:post, 'session/:session_id/moz/context'],
26
28
  install_addon: [:post, 'session/:session_id/moz/addon/install'],
27
- uninstall_addon: [:post, 'session/:session_id/moz/addon/uninstall']
29
+ uninstall_addon: [:post, 'session/:session_id/moz/addon/uninstall'],
30
+ full_page_screenshot: [:get, 'session/:session_id/moz/screenshot/full']
28
31
  }.freeze
29
32
 
30
33
  def commands(command)
31
- COMMANDS[command] || super
34
+ FIREFOX_COMMANDS[command] || self.class::COMMANDS[command]
32
35
  end
33
36
 
34
37
  def install_addon(path, temporary)
38
+ if @file_detector
39
+ local_file = @file_detector.call(path)
40
+ path = upload(local_file) if local_file
41
+ end
42
+
35
43
  payload = {path: path}
36
44
  payload[:temporary] = temporary unless temporary.nil?
37
45
  execute :install_addon, {}, payload
@@ -41,6 +49,17 @@ module Selenium
41
49
  execute :uninstall_addon, {}, {id: id}
42
50
  end
43
51
 
52
+ def full_screenshot
53
+ execute :full_page_screenshot
54
+ end
55
+
56
+ def context=(context)
57
+ execute :set_context, {}, {context: context}
58
+ end
59
+
60
+ def context
61
+ execute :get_context
62
+ end
44
63
  end # Bridge
45
64
  end # Firefox
46
65
  end # WebDriver
@@ -20,12 +20,25 @@
20
20
  module Selenium
21
21
  module WebDriver
22
22
  module Firefox
23
- class Options
24
- attr_reader :args, :prefs, :options, :profile
25
- attr_accessor :binary, :log_level
23
+ class Options < WebDriver::Options
24
+ attr_accessor :debugger_address
26
25
 
27
26
  KEY = 'moz:firefoxOptions'
28
27
 
28
+ # see: https://firefox-source-docs.mozilla.org/testing/geckodriver/Capabilities.html
29
+ CAPABILITIES = {binary: 'binary',
30
+ args: 'args',
31
+ log: 'log',
32
+ prefs: 'prefs',
33
+ android_package: 'androidPackage',
34
+ android_activity: 'androidActivity',
35
+ android_device_serial: 'androidDeviceSerial',
36
+ android_intent_arguments: 'androidIntentArguments'}.freeze
37
+ BROWSER = 'firefox'
38
+
39
+ # NOTE: special handling of 'profile' to validate when set instead of when used
40
+ attr_reader :profile
41
+
29
42
  #
30
43
  # Create a new Options instance, only for W3C-capable versions of Firefox.
31
44
  #
@@ -42,13 +55,16 @@ module Selenium
42
55
  # @option opts [Hash] :options A hash for raw options
43
56
  #
44
57
 
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) || {}
58
+ def initialize(log_level: nil, **opts)
59
+ @debugger_address = opts.delete(:debugger_address)
60
+
61
+ super(**opts)
62
+
63
+ @options[:args] ||= []
64
+ @options[:prefs] ||= {}
65
+ @options[:log] ||= {level: log_level} if log_level
66
+
67
+ process_profile(@options.delete(:profile))
52
68
  end
53
69
 
54
70
  #
@@ -62,22 +78,7 @@ module Selenium
62
78
  #
63
79
 
64
80
  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
+ @options[:args] << arg
81
82
  end
82
83
 
83
84
  #
@@ -92,7 +93,7 @@ module Selenium
92
93
  #
93
94
 
94
95
  def add_preference(name, value)
95
- prefs[name] = value
96
+ @options[:prefs][name] = value
96
97
  end
97
98
 
98
99
  #
@@ -123,38 +124,58 @@ module Selenium
123
124
  #
124
125
 
125
126
  def profile=(profile)
126
- @profile = process_profile(profile)
127
+ process_profile(profile)
127
128
  end
128
129
 
129
- #
130
- # @api private
131
- #
130
+ def log_level
131
+ @options.dig(:log, :level)
132
+ end
132
133
 
133
- def as_json(*)
134
- opts = @options
134
+ def log_level=(level)
135
+ @options[:log] = {level: level}
136
+ end
135
137
 
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
138
+ #
139
+ # Enables mobile browser use on Android.
140
+ #
141
+ # @see https://developer.mozilla.org/en-US/docs/Web/WebDriver/Capabilities/firefoxOptions#android
142
+ #
143
+ # @param [String] package The package name of the Chrome or WebView app.
144
+ # @param [String] serial_number The serial number of the device on which to launch the application.
145
+ # If not specified and multiple devices are attached, an error will be returned.
146
+ # @param [String] activity The fully qualified class name of the activity to be launched.
147
+ # @param [Array] intent_arguments Arguments to launch the intent with.
148
+ #
141
149
 
142
- {KEY => opts}
150
+ def enable_android(package: 'org.mozilla.firefox', serial_number: nil, activity: nil, intent_arguments: nil)
151
+ @options[:android_package] = package
152
+ @options[:android_activity] = activity unless activity.nil?
153
+ @options[:android_device_serial] = serial_number unless serial_number.nil?
154
+ @options[:android_intent_arguments] = intent_arguments unless intent_arguments.nil?
143
155
  end
144
156
 
145
157
  private
146
158
 
159
+ def process_browser_options(browser_options)
160
+ browser_options['moz:debuggerAddress'] = true if @debugger_address
161
+ options = browser_options[KEY]
162
+ options['binary'] ||= Firefox.path if Firefox.path
163
+ options['profile'] = @profile if @profile
164
+ end
165
+
147
166
  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
167
+ @profile = case profile
168
+ when nil
169
+ nil
170
+ when Profile
171
+ profile
172
+ else
173
+ Profile.from_name(profile)
174
+ end
175
+ end
176
+
177
+ def camelize?(key)
178
+ key != :prefs
158
179
  end
159
180
  end # Options
160
181
  end # Firefox
@@ -23,18 +23,18 @@ module Selenium
23
23
  class Profile
24
24
  include ProfileHelper
25
25
 
26
- VALID_PREFERENCE_TYPES = [TrueClass, FalseClass, Integer, Float, String].freeze
27
- WEBDRIVER_EXTENSION_PATH = File.expand_path("#{WebDriver.root}/selenium/webdriver/firefox/extension/webdriver.xpi")
28
- WEBDRIVER_PREFS = {
29
- native_events: 'webdriver_enable_native_events',
30
- untrusted_certs: 'webdriver_accept_untrusted_certs',
31
- untrusted_issuer: 'webdriver_assume_untrusted_issuer',
32
- port: 'webdriver_firefox_port',
33
- log_file: 'webdriver.log.file'
26
+ VALID_PREFERENCE_TYPES = [TrueClass, FalseClass, Integer, Float, String].freeze
27
+
28
+ DEFAULT_PREFERENCES = {
29
+ "browser.newtabpage.enabled" => false,
30
+ "browser.startup.homepage" => "about:blank",
31
+ "browser.usedOnWindows10.introURL" => "about:blank",
32
+ "network.captive-portal-service.enabled" => false,
33
+ "security.csp.enable" => false
34
34
  }.freeze
35
35
 
36
36
  attr_reader :name, :log_file
37
- attr_writer :secure_ssl, :native_events, :load_no_focus_lib
37
+ attr_writer :secure_ssl, :load_no_focus_lib
38
38
 
39
39
  class << self
40
40
  def ini
@@ -48,10 +48,8 @@ module Selenium
48
48
  raise Error::WebDriverError, "unable to find profile named: #{name.inspect}"
49
49
  end
50
50
 
51
- def default_preferences
52
- @default_preferences ||= JSON.parse(
53
- File.read(File.expand_path("#{WebDriver.root}/selenium/webdriver/firefox/extension/prefs.json"))
54
- ).freeze
51
+ def decoded(json)
52
+ JSON.parse(json)
55
53
  end
56
54
  end
57
55
 
@@ -70,14 +68,7 @@ module Selenium
70
68
  def initialize(model = nil)
71
69
  @model = verify_model(model)
72
70
 
73
- model_prefs = read_model_prefs
74
-
75
- if model_prefs.empty?
76
- assign_default_preferences
77
- else
78
- assign_updated_preferences(model_prefs)
79
- end
80
-
71
+ @additional_prefs = read_model_prefs
81
72
  @extensions = {}
82
73
  end
83
74
 
@@ -121,12 +112,6 @@ module Selenium
121
112
  self[WEBDRIVER_PREFS[:log_file]] = file
122
113
  end
123
114
 
124
- def add_webdriver_extension
125
- return if @extensions.key?(:webdriver)
126
-
127
- add_extension(WEBDRIVER_EXTENSION_PATH, :webdriver)
128
- end
129
-
130
115
  #
131
116
  # Add the extension (directory, .zip or .xpi) at the given path to the profile.
132
117
  #
@@ -135,26 +120,6 @@ module Selenium
135
120
  @extensions[name] = Extension.new(path)
136
121
  end
137
122
 
138
- def native_events?
139
- @native_events == true
140
- end
141
-
142
- def load_no_focus_lib?
143
- @load_no_focus_lib == true
144
- end
145
-
146
- def secure_ssl?
147
- @secure_ssl == true
148
- end
149
-
150
- def assume_untrusted_certificate_issuer?
151
- @untrusted_issuer == true
152
- end
153
-
154
- def assume_untrusted_certificate_issuer=(bool)
155
- @untrusted_issuer = bool
156
- end
157
-
158
123
  def proxy=(proxy)
159
124
  raise TypeError, "expected #{Proxy.name}, got #{proxy.inspect}:#{proxy.class}" unless proxy.is_a? Proxy
160
125
 
@@ -178,30 +143,10 @@ module Selenium
178
143
  end
179
144
  end
180
145
 
181
- def encoded
182
- Zipper.zip(layout_on_disk)
183
- end
146
+ alias_method :as_json, :encoded
184
147
 
185
148
  private
186
149
 
187
- def assign_default_preferences
188
- @native_events = DEFAULT_ENABLE_NATIVE_EVENTS
189
- @secure_ssl = DEFAULT_SECURE_SSL
190
- @untrusted_issuer = DEFAULT_ASSUME_UNTRUSTED_ISSUER
191
- @load_no_focus_lib = DEFAULT_LOAD_NO_FOCUS_LIB
192
-
193
- @additional_prefs = {}
194
- end
195
-
196
- def assign_updated_preferences(model_prefs)
197
- @native_events = model_prefs.delete(WEBDRIVER_PREFS[:native_events]) == 'true'
198
- @secure_ssl = model_prefs.delete(WEBDRIVER_PREFS[:untrusted_certs]) != 'true'
199
- @untrusted_issuer = model_prefs.delete(WEBDRIVER_PREFS[:untrusted_issuer]) == 'true'
200
- # not stored in profile atm, so will always be false.
201
- @load_no_focus_lib = model_prefs.delete(WEBDRIVER_PREFS[:load_no_focus_lib]) == 'true'
202
- @additional_prefs = model_prefs
203
- end
204
-
205
150
  def set_manual_proxy_preference(key, value)
206
151
  return unless value
207
152
 
@@ -243,17 +188,11 @@ module Selenium
243
188
  def update_user_prefs_in(directory)
244
189
  path = File.join(directory, 'user.js')
245
190
  prefs = read_user_prefs(path)
246
-
247
- prefs.merge! self.class.default_preferences.fetch 'mutable'
248
- prefs.merge! @additional_prefs
249
- prefs.merge! self.class.default_preferences.fetch 'frozen'
250
-
251
- prefs[WEBDRIVER_PREFS[:untrusted_certs]] = !secure_ssl?
252
- prefs[WEBDRIVER_PREFS[:native_events]] = native_events?
253
- prefs[WEBDRIVER_PREFS[:untrusted_issuer]] = assume_untrusted_certificate_issuer?
191
+ prefs.merge! self.class::DEFAULT_PREFERENCES
192
+ prefs.merge!(@additional_prefs)
254
193
 
255
194
  # If the user sets the home page, we should also start up there
256
- prefs['startup.homepage_welcome_url'] = prefs['browser.startup.homepage']
195
+ prefs['startup.homepage_welcome_url'] ||= prefs['browser.startup.homepage']
257
196
 
258
197
  write_prefs prefs, path
259
198
  end
@@ -20,10 +20,6 @@
20
20
  module Selenium
21
21
  module WebDriver
22
22
  module Firefox
23
- #
24
- # @api private
25
- #
26
-
27
23
  class Service < WebDriver::Service
28
24
  DEFAULT_PORT = 4444
29
25
  EXECUTABLE = 'geckodriver'
@@ -36,7 +32,7 @@ module Selenium
36
32
 
37
33
  private
38
34
 
39
- # Note: This processing is deprecated
35
+ # NOTE: This processing is deprecated
40
36
  def extract_service_args(driver_opts)
41
37
  driver_args = super
42
38
  driver_opts = driver_opts.dup