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
@@ -27,73 +27,43 @@ module Selenium
27
27
  #
28
28
 
29
29
  class Driver < WebDriver::Driver
30
- include DriverExtensions::HasNetworkConditions
31
- include DriverExtensions::HasWebStorage
32
- include DriverExtensions::HasLocation
33
- include DriverExtensions::TakesScreenshot
34
- include DriverExtensions::DownloadsFiles
35
-
36
- def initialize(opts = {})
37
- opts[:desired_capabilities] = create_capabilities(opts)
38
-
39
- opts[:url] ||= service_url(opts)
40
-
41
- listener = opts.delete(:listener)
42
- desired_capabilities = opts.delete(:desired_capabilities)
43
-
44
- @bridge = Remote::Bridge.new(opts)
45
- @bridge.extend Bridge
46
- @bridge.create_session(desired_capabilities)
47
-
48
- super(@bridge, listener: listener)
49
- end
30
+ EXTENSIONS = [DriverExtensions::HasCDP,
31
+ DriverExtensions::HasCasting,
32
+ DriverExtensions::HasNetworkConditions,
33
+ DriverExtensions::HasNetworkInterception,
34
+ DriverExtensions::HasWebStorage,
35
+ DriverExtensions::HasLaunching,
36
+ DriverExtensions::HasLocation,
37
+ DriverExtensions::HasPermissions,
38
+ DriverExtensions::DownloadsFiles,
39
+ DriverExtensions::HasDevTools,
40
+ DriverExtensions::HasAuthentication,
41
+ DriverExtensions::HasLogs,
42
+ DriverExtensions::HasLogEvents,
43
+ DriverExtensions::HasPinnedScripts,
44
+ DriverExtensions::PrintsPage].freeze
50
45
 
51
46
  def browser
52
47
  :chrome
53
48
  end
54
49
 
55
- def quit
56
- super
57
- ensure
58
- @service&.stop
59
- end
60
-
61
- def execute_cdp(cmd, **params)
62
- @bridge.send_command(cmd: cmd, params: params)
63
- end
64
-
65
50
  private
66
51
 
67
- def create_capabilities(opts)
68
- caps = opts.delete(:desired_capabilities) { Remote::Capabilities.chrome }
69
- options = opts.delete(:options) { Options.new }
70
-
71
- profile = opts.delete(:profile)
72
- if profile
73
- profile = profile.as_json
74
-
75
- options.add_argument("--user-data-dir=#{profile[:directory]}") if options.args.none?(&/user-data-dir/.method(:match?))
76
-
77
- if profile[:extensions]
78
- WebDriver.logger.deprecate 'Using Selenium::WebDriver::Chrome::Profile#extensions',
79
- 'Selenium::WebDriver::Chrome::Options#add_extension'
80
- profile[:extensions].each do |extension|
81
- options.add_encoded_extension(extension)
82
- end
83
- end
84
- end
52
+ def devtools_url
53
+ uri = URI(devtools_address)
54
+ response = Net::HTTP.get(uri.hostname, '/json/version', uri.port)
85
55
 
86
- detach = opts.delete(:detach)
87
- options.add_option(:detach, true) if detach
88
-
89
- options = options.as_json
90
- caps.merge!(options) unless options[Options::KEY].empty?
56
+ JSON.parse(response)['webSocketDebuggerUrl']
57
+ end
91
58
 
92
- caps[:proxy] = opts.delete(:proxy) if opts.key?(:proxy)
93
- caps[:proxy] ||= opts.delete('proxy') if opts.key?('proxy')
59
+ def devtools_version
60
+ Integer(capabilities.browser_version.split('.').first)
61
+ end
94
62
 
95
- caps
63
+ def devtools_address
64
+ "http://#{capabilities['goog:chromeOptions']['debuggerAddress']}"
96
65
  end
66
+
97
67
  end # Driver
98
68
  end # Chrome
99
69
  end # WebDriver
@@ -0,0 +1,106 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Licensed to the Software Freedom Conservancy (SFC) under one
4
+ # or more contributor license agreements. See the NOTICE file
5
+ # distributed with this work for additional information
6
+ # regarding copyright ownership. The SFC licenses this file
7
+ # to you under the Apache License, Version 2.0 (the
8
+ # "License"); you may not use this file except in compliance
9
+ # with the License. You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing,
14
+ # software distributed under the License is distributed on an
15
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16
+ # KIND, either express or implied. See the License for the
17
+ # specific language governing permissions and limitations
18
+ # under the License.
19
+
20
+ module Selenium
21
+ module WebDriver
22
+ module Chrome
23
+ module Features
24
+
25
+ CHROME_COMMANDS = {
26
+ launch_app: [:post, 'session/:session_id/chromium/launch_app'],
27
+ get_cast_sinks: [:get, 'session/:session_id/goog/cast/get_sinks'],
28
+ set_cast_sink_to_use: [:post, 'session/:session_id/goog/cast/set_sink_to_use'],
29
+ start_cast_tab_mirroring: [:post, 'session/:session_id/goog/cast/start_tab_mirroring'],
30
+ get_cast_issue_message: [:get, 'session/:session_id/goog/cast/get_issue_message'],
31
+ stop_casting: [:post, 'session/:session_id/goog/cast/stop_casting'],
32
+ get_network_conditions: [:get, 'session/:session_id/chromium/network_conditions'],
33
+ set_network_conditions: [:post, 'session/:session_id/chromium/network_conditions'],
34
+ delete_network_conditions: [:delete, 'session/:session_id/chromium/network_conditions'],
35
+ set_permission: [:post, 'session/:session_id/permissions'],
36
+ send_command: [:post, 'session/:session_id/goog/cdp/execute'],
37
+ get_available_log_types: [:get, 'session/:session_id/se/log/types'],
38
+ get_log: [:post, 'session/:session_id/se/log']
39
+ }.freeze
40
+
41
+ def commands(command)
42
+ CHROME_COMMANDS[command] || self.class::COMMANDS[command]
43
+ end
44
+
45
+ def launch_app(id)
46
+ execute :launch_app, {}, {id: id}
47
+ end
48
+
49
+ def cast_sinks
50
+ execute :get_cast_sinks
51
+ end
52
+
53
+ def cast_sink_to_use=(name)
54
+ execute :set_cast_sink_to_use, {}, {sinkName: name}
55
+ end
56
+
57
+ def cast_issue_message
58
+ execute :cast_issue_message
59
+ end
60
+
61
+ def start_cast_tab_mirroring(name)
62
+ execute :start_cast_tab_mirroring, {}, {sinkName: name}
63
+ end
64
+
65
+ def stop_casting(name)
66
+ execute :stop_casting, {}, {sinkName: name}
67
+ end
68
+
69
+ def set_permission(name, value)
70
+ execute :set_permission, {}, {descriptor: {name: name}, state: value}
71
+ end
72
+
73
+ def network_conditions
74
+ execute :get_network_conditions
75
+ end
76
+
77
+ def network_conditions=(conditions)
78
+ execute :set_network_conditions, {}, {network_conditions: conditions}
79
+ end
80
+
81
+ def delete_network_conditions
82
+ execute :delete_network_conditions
83
+ end
84
+
85
+ def send_command(command_params)
86
+ execute :send_command, {}, command_params
87
+ end
88
+
89
+ def available_log_types
90
+ types = execute :get_available_log_types
91
+ Array(types).map(&:to_sym)
92
+ end
93
+
94
+ def log(type)
95
+ data = execute :get_log, {}, {type: type.to_s}
96
+
97
+ Array(data).map do |l|
98
+ LogEntry.new l.fetch('level', 'UNKNOWN'), l.fetch('timestamp'), l.fetch('message')
99
+ rescue KeyError
100
+ next
101
+ end
102
+ end
103
+ end # Bridge
104
+ end # Chrome
105
+ end # WebDriver
106
+ end # Selenium
@@ -20,19 +20,40 @@
20
20
  module Selenium
21
21
  module WebDriver
22
22
  module Chrome
23
- class Options
24
- attr_reader :args, :prefs, :options, :emulation, :extensions, :encoded_extensions
25
- attr_accessor :binary
23
+ class Options < WebDriver::Options
24
+ attr_accessor :profile, :logging_prefs
26
25
 
27
26
  KEY = 'goog:chromeOptions'
27
+ BROWSER = 'chrome'
28
+
29
+ # see: http://chromedriver.chromium.org/capabilities
30
+ CAPABILITIES = {args: 'args',
31
+ binary: 'binary',
32
+ local_state: 'localState',
33
+ prefs: 'prefs',
34
+ detach: 'detach',
35
+ debugger_address: 'debuggerAddress',
36
+ exclude_switches: 'excludeSwitches',
37
+ minidump_path: 'minidumpPath',
38
+ emulation: 'mobileEmulation',
39
+ perf_logging_prefs: 'perfLoggingPrefs',
40
+ window_types: 'windowTypes',
41
+ android_package: 'androidPackage',
42
+ android_activity: 'androidActivity',
43
+ android_device_serial: 'androidDeviceSerial',
44
+ android_use_running_app: 'androidUseRunningApp'}.freeze
45
+
46
+ # NOTE: special handling of 'extensions' to validate when set instead of when used
47
+ attr_reader :extensions
28
48
 
29
- #
30
49
  # Create a new Options instance.
31
50
  #
32
51
  # @example
33
52
  # options = Selenium::WebDriver::Chrome::Options.new(args: ['start-maximized', 'user-data-dir=/tmp/temp_profile'])
34
53
  # driver = Selenium::WebDriver.for(:chrome, options: options)
35
54
  #
55
+ # @param [Profile] :profile An instance of a Chrome::Profile Class
56
+ # @param [Array] :encoded_extensions List of extensions that do not need to be Base64 encoded
36
57
  # @param [Hash] opts the pre-defined options to create the Chrome::Options with
37
58
  # @option opts [Array<String>] :args List of command-line arguments to use when starting Chrome
38
59
  # @option opts [String] :binary Path to the Chrome executable to use
@@ -40,16 +61,33 @@ module Selenium
40
61
  # @option opts [Array<String>] :extensions A list of paths to (.crx) Chrome extensions to install on startup
41
62
  # @option opts [Hash] :options A hash for raw options
42
63
  # @option opts [Hash] :emulation A hash for raw emulation options
64
+ # @option opts [Hash] :local_state A hash for the Local State file in the user data folder
65
+ # @option opts [Boolean] :detach whether browser is closed when the driver is sent the quit command
66
+ # @option opts [String] :debugger_address address of a Chrome debugger server to connect to
67
+ # @option opts [Array<String>] :exclude_switches command line switches to exclude
68
+ # @option opts [String] :minidump_path Directory to store Chrome minidumps (linux only)
69
+ # @option opts [Hash] :perf_logging_prefs A hash for performance logging preferences
70
+ # @option opts [Array<String>] :window_types A list of window types to appear in the list of window handles
43
71
  #
44
72
 
45
- def initialize(**opts)
46
- @args = Set.new(opts.delete(:args) || [])
47
- @binary = opts.delete(:binary) || Chrome.path
48
- @prefs = opts.delete(:prefs) || {}
49
- @extensions = opts.delete(:extensions) || []
50
- @options = opts.delete(:options) || {}
51
- @emulation = opts.delete(:emulation) || {}
52
- @encoded_extensions = []
73
+ def initialize(profile: nil, **opts)
74
+ super(**opts)
75
+
76
+ @profile = profile
77
+
78
+ @options = {args: [],
79
+ prefs: {},
80
+ emulation: {},
81
+ extensions: [],
82
+ local_state: {},
83
+ exclude_switches: [],
84
+ perf_logging_prefs: {},
85
+ window_types: []}.merge(@options)
86
+
87
+ @logging_prefs = options.delete(:logging_prefs) || {}
88
+ @encoded_extensions = @options.delete(:encoded_extensions) || []
89
+ @extensions = []
90
+ (@options.delete(:extensions)).each(&method(:validate_extension))
53
91
  end
54
92
 
55
93
  #
@@ -63,10 +101,22 @@ module Selenium
63
101
  #
64
102
 
65
103
  def add_extension(path)
66
- raise Error::WebDriverError, "could not find extension at #{path.inspect}" unless File.file?(path)
67
- raise Error::WebDriverError, "file was not an extension #{path.inspect}" unless File.extname(path) == '.crx'
104
+ validate_extension(path)
105
+ end
68
106
 
69
- @extensions << path
107
+ #
108
+ # Add an extension by local path.
109
+ #
110
+ # @example
111
+ # extensions = ['/path/to/extension.crx', '/path/to/other.crx']
112
+ # options = Selenium::WebDriver::Chrome::Options.new
113
+ # options.extensions = extensions
114
+ #
115
+ # @param [Array<String>] :extensions A list of paths to (.crx) Chrome extensions to install on startup
116
+ #
117
+
118
+ def extensions=(extensions)
119
+ extensions.each(&method(:validate_extension))
70
120
  end
71
121
 
72
122
  #
@@ -94,22 +144,7 @@ module Selenium
94
144
  #
95
145
 
96
146
  def add_argument(arg)
97
- @args << arg
98
- end
99
-
100
- #
101
- # Add a new option not yet handled by bindings.
102
- #
103
- # @example Leave Chrome open when chromedriver is killed
104
- # options = Selenium::WebDriver::Chrome::Options.new
105
- # options.add_option(:detach, true)
106
- #
107
- # @param [String, Symbol] name Name of the option
108
- # @param [Boolean, String, Integer] value Value of the option
109
- #
110
-
111
- def add_option(name, value)
112
- @options[name] = value
147
+ @options[:args] << arg
113
148
  end
114
149
 
115
150
  #
@@ -124,7 +159,7 @@ module Selenium
124
159
  #
125
160
 
126
161
  def add_preference(name, value)
127
- prefs[name] = value
162
+ @options[:prefs][name] = value
128
163
  end
129
164
 
130
165
  #
@@ -140,7 +175,9 @@ module Selenium
140
175
  end
141
176
 
142
177
  #
143
- # Add an emulation device name
178
+ # Add emulation device information
179
+ #
180
+ # see: http://chromedriver.chromium.org/mobile-emulation
144
181
  #
145
182
  # @example Start Chrome in mobile emulation mode by device name
146
183
  # options = Selenium::WebDriver::Chrome::Options.new
@@ -150,35 +187,73 @@ module Selenium
150
187
  # options = Selenium::WebDriver::Chrome::Options.new
151
188
  # options.add_emulation(device_metrics: {width: 400, height: 800, pixelRatio: 1, touch: true})
152
189
  #
153
- # @param [String] device_name Name of the device or a hash containing width, height, pixelRatio, touch
154
- # @param [Hash] device_metrics Hash containing width, height, pixelRatio, touch
155
- # @param [String] user_agent Full user agent
190
+ # @param [Hash] opts the pre-defined options for adding mobile emulation values
191
+ # @option opts [String] :device_name A valid device name from the Chrome DevTools Emulation panel
192
+ # @option opts [Hash] :device_metrics Hash containing width, height, pixelRatio, touch
193
+ # @option opts [String] :user_agent Full user agent
156
194
  #
157
195
 
158
- def add_emulation(device_name: nil, device_metrics: nil, user_agent: nil)
159
- @emulation[:deviceName] = device_name if device_name
160
- @emulation[:deviceMetrics] = device_metrics if device_metrics
161
- @emulation[:userAgent] = user_agent if user_agent
196
+ def add_emulation(**opts)
197
+ @options[:emulation] = opts
162
198
  end
163
199
 
164
200
  #
165
- # @api private
201
+ # Enables mobile browser use on Android.
166
202
  #
203
+ # @see https://chromedriver.chromium.org/getting-started/getting-started---android
204
+ #
205
+ # @param [String] package The package name of the Chrome or WebView app.
206
+ # @param [String] serial_number The device serial number on which to launch the Chrome or WebView app.
207
+ # @param [String] use_running_app When true uses an already-running Chrome or WebView app,
208
+ # instead of launching the app with a clear data directory.
209
+ # @param [String] activity Name of the Activity hosting the WebView (Not available on Chrome Apps).
210
+ #
211
+
212
+ def enable_android(package: 'com.android.chrome', serial_number: nil, use_running_app: nil, activity: nil)
213
+ @options[:android_package] = package
214
+ @options[:android_activity] = activity unless activity.nil?
215
+ @options[:android_device_serial] = serial_number unless serial_number.nil?
216
+ @options[:android_use_running_app] = use_running_app unless use_running_app.nil?
217
+ end
218
+
219
+ private
220
+
221
+ def enable_logging(browser_options)
222
+ browser_options['goog:loggingPrefs'] = @logging_prefs
223
+ end
224
+
225
+ def process_browser_options(browser_options)
226
+ enable_logging(browser_options) unless @logging_prefs.empty?
167
227
 
168
- def as_json(*)
169
- extensions = @extensions.map do |crx_path|
170
- File.open(crx_path, 'rb') { |crx_file| Base64.strict_encode64 crx_file.read }
228
+ options = browser_options[self.class::KEY]
229
+ options['binary'] ||= binary_path if binary_path
230
+ if @profile
231
+ options['args'] ||= []
232
+ options['args'] << "--user-data-dir=#{@profile.directory}"
171
233
  end
172
- extensions.concat(@encoded_extensions)
173
234
 
174
- opts = @options
175
- opts[:binary] = @binary if @binary
176
- opts[:args] = @args.to_a if @args.any?
177
- opts[:extensions] = extensions if extensions.any?
178
- opts[:mobileEmulation] = @emulation unless @emulation.empty?
179
- opts[:prefs] = @prefs unless @prefs.empty?
235
+ return if (@encoded_extensions + @extensions).empty?
236
+
237
+ options['extensions'] = @encoded_extensions + @extensions.map(&method(:encode_extension))
238
+ end
239
+
240
+ def binary_path
241
+ Chrome.path
242
+ end
243
+
244
+ def encode_extension(path)
245
+ File.open(path, 'rb') { |crx_file| Base64.strict_encode64 crx_file.read }
246
+ end
247
+
248
+ def validate_extension(path)
249
+ raise Error::WebDriverError, "could not find extension at #{path.inspect}" unless File.file?(path)
250
+ raise Error::WebDriverError, "file was not an extension #{path.inspect}" unless File.extname(path) == '.crx'
251
+
252
+ @extensions << path
253
+ end
180
254
 
181
- {KEY => opts}
255
+ def camelize?(key)
256
+ !%w[localState prefs].include?(key)
182
257
  end
183
258
  end # Options
184
259
  end # Chrome
@@ -27,12 +27,11 @@ module Selenium
27
27
  class Profile
28
28
  include ProfileHelper
29
29
 
30
- attr_reader :directory
31
-
32
30
  def initialize(model = nil)
33
31
  @model = verify_model(model)
34
32
  @extensions = []
35
33
  @encoded_extensions = []
34
+ @directory = nil
36
35
  end
37
36
 
38
37
  def add_extension(path)
@@ -45,10 +44,14 @@ module Selenium
45
44
  @encoded_extensions << encoded
46
45
  end
47
46
 
47
+ def directory
48
+ @directory || layout_on_disk
49
+ end
50
+
48
51
  #
49
52
  # Set a preference in the profile.
50
53
  #
51
- # See https://src.chromium.org/svn/trunk/src/chrome/common/pref_names.cc
54
+ # See https://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/pref_names.cc
52
55
  #
53
56
 
54
57
  def []=(key, value)
@@ -77,8 +80,8 @@ module Selenium
77
80
 
78
81
  extensions.concat(@encoded_extensions)
79
82
 
80
- opts = {directory: directory || layout_on_disk}
81
- opts[:extensions] = extensions if extensions.any?
83
+ opts = {'directory' => directory || layout_on_disk}
84
+ opts['extensions'] = extensions if extensions.any?
82
85
  opts
83
86
  end
84
87
 
@@ -20,10 +20,6 @@
20
20
  module Selenium
21
21
  module WebDriver
22
22
  module Chrome
23
- #
24
- # @api private
25
- #
26
-
27
23
  class Service < WebDriver::Service
28
24
  DEFAULT_PORT = 9515
29
25
  EXECUTABLE = 'chromedriver'
@@ -36,14 +32,16 @@ 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
43
39
  driver_args << "--log-path=#{driver_opts.delete(:log_path)}" if driver_opts.key?(:log_path)
44
40
  driver_args << "--url-base=#{driver_opts.delete(:url_base)}" if driver_opts.key?(:url_base)
45
41
  driver_args << "--port-server=#{driver_opts.delete(:port_server)}" if driver_opts.key?(:port_server)
46
- driver_args << "--whitelisted-ips=#{driver_opts.delete(:whitelisted_ips)}" if driver_opts.key?(:whitelisted_ips)
42
+ if driver_opts.key?(:whitelisted_ips)
43
+ driver_args << "--whitelisted-ips=#{driver_opts.delete(:whitelisted_ips)}"
44
+ end
47
45
  driver_args << "--verbose" if driver_opts.key?(:verbose)
48
46
  driver_args << "--silent" if driver_opts.key?(:silent)
49
47
  driver_args
@@ -19,23 +19,26 @@
19
19
 
20
20
  require 'net/http'
21
21
 
22
- require 'selenium/webdriver/chrome/bridge'
23
- require 'selenium/webdriver/chrome/driver'
24
- require 'selenium/webdriver/chrome/profile'
25
- require 'selenium/webdriver/chrome/options'
26
-
27
22
  module Selenium
28
23
  module WebDriver
29
24
  module Chrome
25
+ autoload :Features, 'selenium/webdriver/chrome/features'
26
+ autoload :Driver, 'selenium/webdriver/chrome/driver'
27
+ autoload :Profile, 'selenium/webdriver/chrome/profile'
28
+ autoload :Options, 'selenium/webdriver/chrome/options'
29
+ autoload :Service, 'selenium/webdriver/chrome/service'
30
+
30
31
  def self.driver_path=(path)
31
32
  WebDriver.logger.deprecate 'Selenium::WebDriver::Chrome#driver_path=',
32
- 'Selenium::WebDriver::Chrome::Service#driver_path='
33
+ 'Selenium::WebDriver::Chrome::Service#driver_path=',
34
+ id: :driver_path
33
35
  Selenium::WebDriver::Chrome::Service.driver_path = path
34
36
  end
35
37
 
36
38
  def self.driver_path
37
39
  WebDriver.logger.deprecate 'Selenium::WebDriver::Chrome#driver_path',
38
- 'Selenium::WebDriver::Chrome::Service#driver_path'
40
+ 'Selenium::WebDriver::Chrome::Service#driver_path',
41
+ id: :driver_path
39
42
  Selenium::WebDriver::Chrome::Service.driver_path
40
43
  end
41
44
 
@@ -50,5 +53,3 @@ module Selenium
50
53
  end # Chrome
51
54
  end # WebDriver
52
55
  end # Selenium
53
-
54
- require 'selenium/webdriver/chrome/service'