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.
- checksums.yaml +5 -5
- data/CHANGES +338 -4
- data/Gemfile +3 -1
- data/LICENSE +1 -1
- data/NOTICE +2 -0
- data/README.md +4 -5
- data/lib/selenium/server.rb +21 -29
- data/lib/selenium/webdriver/atoms/findElements.js +122 -0
- data/lib/selenium/webdriver/atoms/getAttribute.js +100 -7
- data/lib/selenium/webdriver/atoms/isDisplayed.js +76 -78
- data/lib/selenium/webdriver/atoms/mutationListener.js +55 -0
- data/lib/selenium/webdriver/chrome/driver.rb +26 -56
- data/lib/selenium/webdriver/chrome/features.rb +106 -0
- data/lib/selenium/webdriver/chrome/options.rb +127 -52
- data/lib/selenium/webdriver/chrome/profile.rb +8 -5
- data/lib/selenium/webdriver/chrome/service.rb +4 -6
- data/lib/selenium/webdriver/chrome.rb +10 -9
- data/lib/selenium/webdriver/common/driver.rb +110 -19
- data/lib/selenium/webdriver/common/driver_extensions/full_page_screenshot.rb +43 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_apple_permissions.rb +51 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_authentication.rb +89 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_casting.rb +77 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_cdp.rb +38 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_context.rb +45 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_devtools.rb +43 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_launching.rb +38 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_location.rb +5 -8
- data/lib/selenium/webdriver/common/driver_extensions/has_log_events.rb +144 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_logs.rb +30 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_network_conditions.rb +17 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_network_connection.rb +6 -27
- data/lib/selenium/webdriver/common/driver_extensions/has_network_interception.rb +136 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_permissions.rb +11 -11
- data/lib/selenium/webdriver/common/driver_extensions/has_pinned_scripts.rb +77 -0
- data/lib/selenium/webdriver/common/driver_extensions/has_remote_status.rb +1 -0
- data/lib/selenium/webdriver/common/driver_extensions/{rotatable.rb → prints_page.rb} +18 -20
- data/lib/selenium/webdriver/common/element.rb +79 -16
- data/lib/selenium/webdriver/common/error.rb +12 -0
- data/lib/selenium/webdriver/common/interactions/interaction.rb +4 -1
- data/lib/selenium/webdriver/common/log_entry.rb +2 -2
- data/lib/selenium/webdriver/common/logger.rb +50 -15
- data/lib/selenium/webdriver/common/manager.rb +14 -14
- data/lib/selenium/webdriver/common/options.rb +186 -0
- data/lib/selenium/webdriver/common/platform.rb +6 -1
- data/lib/selenium/webdriver/common/port_prober.rb +4 -6
- data/lib/selenium/webdriver/common/profile_helper.rb +10 -2
- data/lib/selenium/webdriver/common/proxy.rb +6 -3
- data/lib/selenium/webdriver/common/search_context.rb +7 -3
- data/lib/selenium/webdriver/common/service.rb +23 -113
- data/lib/selenium/webdriver/common/service_manager.rb +151 -0
- data/lib/selenium/webdriver/common/shadow_root.rb +87 -0
- data/lib/selenium/webdriver/common/socket_lock.rb +2 -2
- data/lib/selenium/webdriver/common/takes_screenshot.rb +66 -0
- data/lib/selenium/webdriver/common/target_locator.rb +32 -4
- data/lib/selenium/webdriver/common/timeouts.rb +31 -4
- data/lib/selenium/webdriver/common/wait.rb +1 -1
- data/lib/selenium/webdriver/common/window.rb +0 -4
- data/lib/selenium/webdriver/common.rb +17 -2
- data/lib/selenium/webdriver/devtools/console_event.rb +38 -0
- data/lib/selenium/webdriver/devtools/exception_event.rb +36 -0
- data/lib/selenium/webdriver/devtools/mutation_event.rb +37 -0
- data/lib/selenium/webdriver/{chrome/bridge.rb → devtools/pinned_script.rb} +26 -17
- data/lib/selenium/webdriver/devtools/request.rb +67 -0
- data/lib/selenium/webdriver/devtools/response.rb +66 -0
- data/lib/selenium/webdriver/devtools.rb +182 -0
- data/lib/selenium/webdriver/edge/driver.rb +5 -31
- data/lib/selenium/webdriver/edge/features.rb +44 -0
- data/lib/selenium/webdriver/edge/options.rb +11 -48
- data/lib/selenium/webdriver/edge/profile.rb +33 -0
- data/lib/selenium/webdriver/edge/service.rb +9 -24
- data/lib/selenium/webdriver/edge.rb +11 -13
- data/lib/selenium/webdriver/firefox/driver.rb +20 -30
- data/lib/selenium/webdriver/firefox/extension.rb +8 -0
- data/lib/selenium/webdriver/firefox/{bridge.rb → features.rb} +23 -4
- data/lib/selenium/webdriver/firefox/options.rb +70 -49
- data/lib/selenium/webdriver/firefox/profile.rb +16 -77
- data/lib/selenium/webdriver/firefox/service.rb +1 -5
- data/lib/selenium/webdriver/firefox.rb +22 -16
- data/lib/selenium/webdriver/ie/driver.rb +1 -34
- data/lib/selenium/webdriver/ie/options.rb +13 -44
- data/lib/selenium/webdriver/ie/service.rb +9 -11
- data/lib/selenium/webdriver/ie.rb +8 -7
- data/lib/selenium/webdriver/remote/bridge.rb +112 -86
- data/lib/selenium/webdriver/remote/capabilities.rb +120 -62
- data/lib/selenium/webdriver/remote/commands.rb +7 -0
- data/lib/selenium/webdriver/remote/driver.rb +15 -12
- data/lib/selenium/webdriver/remote/http/common.rb +0 -5
- data/lib/selenium/webdriver/remote/http/default.rb +17 -11
- data/lib/selenium/webdriver/remote/http/persistent.rb +11 -6
- data/lib/selenium/webdriver/remote.rb +15 -9
- data/lib/selenium/webdriver/safari/driver.rb +3 -34
- data/lib/selenium/webdriver/safari/{bridge.rb → features.rb} +6 -6
- data/lib/selenium/webdriver/safari/options.rb +10 -29
- data/lib/selenium/webdriver/safari/service.rb +0 -4
- data/lib/selenium/webdriver/safari.rb +16 -8
- data/lib/selenium/webdriver/support/block_event_listener.rb +1 -1
- data/lib/selenium/webdriver/support/cdp/domain.rb.erb +63 -0
- data/lib/selenium/webdriver/support/cdp_client_generator.rb +108 -0
- data/lib/selenium/webdriver/support/color.rb +2 -2
- data/lib/selenium/webdriver/support/event_firing_bridge.rb +4 -4
- data/lib/selenium/webdriver/support/guards/guard.rb +89 -0
- data/lib/selenium/webdriver/support/guards/guard_condition.rb +52 -0
- data/lib/selenium/webdriver/support/guards.rb +95 -0
- data/lib/selenium/webdriver/support/relative_locator.rb +51 -0
- data/lib/selenium/webdriver/support/select.rb +2 -2
- data/lib/selenium/webdriver/support.rb +1 -0
- data/lib/selenium/webdriver/version.rb +1 -1
- data/lib/selenium/webdriver.rb +10 -8
- data/selenium-webdriver.gemspec +29 -13
- metadata +125 -51
- data/lib/selenium/webdriver/common/driver_extensions/takes_screenshot.rb +0 -64
- data/lib/selenium/webdriver/firefox/binary.rb +0 -110
- 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
|
-
|
|
25
|
-
|
|
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
|
|
43
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
32
|
-
|
|
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 =
|
|
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 #
|
|
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
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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.
|
|
35
|
-
|
|
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
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
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
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
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
|
-
|
|
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
|
|
23
|
+
module Features
|
|
24
24
|
|
|
25
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
@
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
@
|
|
51
|
-
@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
|
-
|
|
127
|
+
process_profile(profile)
|
|
127
128
|
end
|
|
128
129
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
130
|
+
def log_level
|
|
131
|
+
@options.dig(:log, :level)
|
|
132
|
+
end
|
|
132
133
|
|
|
133
|
-
def
|
|
134
|
-
|
|
134
|
+
def log_level=(level)
|
|
135
|
+
@options[:log] = {level: level}
|
|
136
|
+
end
|
|
135
137
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
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
|
-
|
|
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
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
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
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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, :
|
|
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
|
|
52
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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!
|
|
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']
|
|
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
|
-
#
|
|
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
|