selenium-webdriver 4.14.0 → 4.15.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dc5fa0275bc4e0f7675b6579bb652cb2efc20bc47797407a3c1da5cd3ac61959
4
- data.tar.gz: 35d845b2fab6603c02c7c6d56f8b2e2e21aa956ed1fcbe01adc0ec0e1b4627d6
3
+ metadata.gz: 2005eb5039203a271b3d3bc3bacbe8e184e7bed9d145eaf3a87295456cf1a8e8
4
+ data.tar.gz: b94d892de1f0c8b6e19d9ff4831cd075b0d56d765b754d3797b8d2f15468343f
5
5
  SHA512:
6
- metadata.gz: 61ce01ca9e41da013f55b0a970f3c4fe68e496132fd3f70c7a4770e1874dfdbc3a0102e530cbc01e9e4cfc4dd02614eee6120366471e2e07da9cb0d097222e78
7
- data.tar.gz: 00ebdefe7adc44e8d535a6ab2099ea6233d6a2d9d5c2960a93ac001c34657a7860857e3387c3c93053f034bcccda4dc8120325c105c16bd0ba7151acb8e1211e
6
+ metadata.gz: d5bb85e63490bbb9f1ecd49bf5fb5a2ebf21b79b5fb4bb41162c43c62d6e73da4142e7b8c13b449ae8909958e9169049d4770b2d3e206337a1645e0a5b002c92
7
+ data.tar.gz: 136cd21751e98c3bd737a8f1e954671124a339674221151cd00f992d1067349d42a92dc1d64dc32e0e157a9f52227215be8c76cb1eca9133a46774fc30101426
data/CHANGES CHANGED
@@ -1,4 +1,13 @@
1
- 4.14.0 (Unreleased)
1
+ 4.15.0 (unreleased)
2
+ =========================
3
+
4
+ * Do not set browser binary in selenium manager if it is an empty string (#12738)
5
+ * Add flaky condition to guards to mark unreliable tests
6
+ * Rake update needs to build latest grid for running remote tests
7
+ * Add CDP v119 and remove v116
8
+ * Implement file downloads (#12979)
9
+
10
+ 4.14.0 (2023-10-09)
2
11
  =========================
3
12
  Ruby:
4
13
  * allow users to access the full script of the atom directly
Binary file
Binary file
Binary file
@@ -35,8 +35,12 @@ module Selenium
35
35
  send_command: [:post, 'session/:session_id/goog/cdp/execute']
36
36
  }.freeze
37
37
 
38
+ def command_list
39
+ CHROME_COMMANDS.merge(CHROMIUM_COMMANDS).merge(self.class::COMMANDS)
40
+ end
41
+
38
42
  def commands(command)
39
- CHROME_COMMANDS[command] || CHROMIUM_COMMANDS[command] || self.class::COMMANDS[command]
43
+ command_list[command]
40
44
  end
41
45
  end # Bridge
42
46
  end # Chrome
@@ -31,10 +31,6 @@ module Selenium
31
31
  get_log: [:post, 'session/:session_id/se/log']
32
32
  }.freeze
33
33
 
34
- def commands(command)
35
- CHROME_COMMANDS[command] || self.class::COMMANDS[command]
36
- end
37
-
38
34
  def launch_app(id)
39
35
  execute :launch_app, {}, {id: id}
40
36
  end
@@ -0,0 +1,65 @@
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 DriverExtensions
23
+ module HasFileDownloads
24
+ def downloadable_files
25
+ verify_enabled
26
+
27
+ @bridge.downloadable_files['names']
28
+ end
29
+
30
+ def download_file(file_name, target_directory)
31
+ verify_enabled
32
+
33
+ response = @bridge.download_file(file_name)
34
+ contents = response['contents']
35
+
36
+ File.open("#{file_name}.zip", 'wb') { |f| f << Base64.decode64(contents) }
37
+ target_directory += '/' unless target_directory.end_with?('/')
38
+ FileUtils.mkdir_p(target_directory)
39
+
40
+ begin
41
+ Zip::File.open("#{file_name}.zip") do |zip|
42
+ zip.each { |entry| zip.extract(entry, "#{target_directory}#{file_name}") }
43
+ end
44
+ ensure
45
+ FileUtils.rm_f("#{file_name}.zip")
46
+ end
47
+ end
48
+
49
+ def delete_downloadable_files
50
+ verify_enabled
51
+
52
+ @bridge.delete_downloadable_files
53
+ end
54
+
55
+ private
56
+
57
+ def verify_enabled
58
+ return if capabilities['se:downloadsEnabled']
59
+
60
+ raise Error::WebDriverError, 'You must enable downloads in order to work with downloadable files.'
61
+ end
62
+ end # HasFileDownloads
63
+ end # DriverExtensions
64
+ end # WebDriver
65
+ end # Selenium
@@ -24,6 +24,8 @@ module Selenium
24
24
  set_window_rect timeouts unhandled_prompt_behavior strict_file_interactability
25
25
  web_socket_url].freeze
26
26
 
27
+ GRID_OPTIONS = %i[enable_downloads].freeze
28
+
27
29
  class << self
28
30
  attr_reader :driver_path
29
31
 
@@ -104,6 +106,8 @@ module Selenium
104
106
  def as_json(*)
105
107
  options = @options.dup
106
108
 
109
+ downloads = options.delete(:enable_downloads)
110
+ options['se:downloadsEnabled'] = downloads unless downloads.nil?
107
111
  w3c_options = process_w3c_options(options)
108
112
 
109
113
  browser_options = self.class::CAPABILITIES.each_with_object({}) do |(capability_alias, capability_name), hash|
@@ -45,7 +45,7 @@ module Selenium
45
45
  driver_path = output['driver_path']
46
46
  Platform.assert_executable driver_path
47
47
 
48
- if options.respond_to? :binary
48
+ if options.respond_to?(:binary) && browser_path && !browser_path.empty?
49
49
  options.binary = browser_path
50
50
  options.browser_version = nil
51
51
  end
@@ -81,6 +81,7 @@ require 'selenium/webdriver/common/driver_extensions/full_page_screenshot'
81
81
  require 'selenium/webdriver/common/driver_extensions/has_addons'
82
82
  require 'selenium/webdriver/common/driver_extensions/has_bidi'
83
83
  require 'selenium/webdriver/common/driver_extensions/has_devtools'
84
+ require 'selenium/webdriver/common/driver_extensions/has_file_downloads'
84
85
  require 'selenium/webdriver/common/driver_extensions/has_authentication'
85
86
  require 'selenium/webdriver/common/driver_extensions/has_logs'
86
87
  require 'selenium/webdriver/common/driver_extensions/has_log_events'
@@ -35,8 +35,12 @@ module Selenium
35
35
  send_command: [:post, 'session/:session_id/ms/cdp/execute']
36
36
  }.freeze
37
37
 
38
+ def command_list
39
+ EDGE_COMMANDS.merge(CHROMIUM_COMMANDS).merge(self.class::COMMANDS)
40
+ end
41
+
38
42
  def commands(command)
39
- EDGE_COMMANDS[command] || CHROMIUM_COMMANDS[command] || self.class::COMMANDS[command]
43
+ command_list[command]
40
44
  end
41
45
  end # Bridge
42
46
  end # Edge
@@ -29,8 +29,12 @@ module Selenium
29
29
  full_page_screenshot: [:get, 'session/:session_id/moz/screenshot/full']
30
30
  }.freeze
31
31
 
32
+ def command_list
33
+ FIREFOX_COMMANDS.merge(self.class::COMMANDS)
34
+ end
35
+
32
36
  def commands(command)
33
- FIREFOX_COMMANDS[command] || self.class::COMMANDS[command]
37
+ command_list[command]
34
38
  end
35
39
 
36
40
  def install_addon(path, temporary)
@@ -0,0 +1,34 @@
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 IE
23
+ module Features
24
+ def command_list
25
+ self.class::COMMANDS
26
+ end
27
+
28
+ def commands(command)
29
+ command_list[command]
30
+ end
31
+ end # Bridge
32
+ end # Ie
33
+ end # WebDriver
34
+ end # Selenium
@@ -20,9 +20,10 @@
20
20
  module Selenium
21
21
  module WebDriver
22
22
  module IE
23
- autoload :Driver, 'selenium/webdriver/ie/driver'
24
- autoload :Options, 'selenium/webdriver/ie/options'
25
- autoload :Service, 'selenium/webdriver/ie/service'
23
+ autoload :Features, 'selenium/webdriver/ie/features'
24
+ autoload :Driver, 'selenium/webdriver/ie/driver'
25
+ autoload :Options, 'selenium/webdriver/ie/options'
26
+ autoload :Service, 'selenium/webdriver/ie/service'
26
27
  end # IE
27
28
  end # WebDriver
28
29
  end # Selenium
@@ -144,12 +144,6 @@ module Selenium
144
144
  take_screenshot: [:get, 'session/:session_id/screenshot'],
145
145
  take_element_screenshot: [:get, 'session/:session_id/element/:id/screenshot'],
146
146
 
147
- #
148
- # server extensions
149
- #
150
-
151
- upload_file: [:post, 'session/:session_id/se/file'],
152
-
153
147
  #
154
148
  # virtual-authenticator
155
149
  #
@@ -391,30 +391,11 @@ module Selenium
391
391
  end
392
392
 
393
393
  def send_keys_to_element(element, keys)
394
- # TODO: rework file detectors before Selenium 4.0
395
- if @file_detector
396
- local_files = keys.first&.split("\n")&.map { |key| @file_detector.call(Array(key)) }&.compact
397
- if local_files&.any?
398
- keys = local_files.map { |local_file| upload(local_file) }
399
- keys = Array(keys.join("\n"))
400
- end
401
- end
402
-
403
- # Keep .split(//) for backward compatibility for now
394
+ keys = upload_if_necessary(keys) if @file_detector
404
395
  text = keys.join
405
396
  execute :element_send_keys, {id: element}, {value: text.chars, text: text}
406
397
  end
407
398
 
408
- def upload(local_file)
409
- unless File.file?(local_file)
410
- WebDriver.logger.debug("File detector only works with files. #{local_file.inspect} isn`t a file!",
411
- id: :file_detector)
412
- raise Error::WebDriverError, "You are trying to work with something that isn't a file."
413
- end
414
-
415
- execute :upload_file, {}, {file: Zipper.zip_file(local_file)}
416
- end
417
-
418
399
  def clear_element(element)
419
400
  execute :element_clear, id: element
420
401
  end
@@ -28,6 +28,7 @@ module Selenium
28
28
  class Driver < WebDriver::Driver
29
29
  include DriverExtensions::UploadsFiles
30
30
  include DriverExtensions::HasSessionId
31
+ include DriverExtensions::HasFileDownloads
31
32
 
32
33
  def initialize(capabilities: nil, options: nil, service: nil, url: nil, **opts)
33
34
  raise ArgumentError, "Can not set :service object on #{self.class}" if service
@@ -36,6 +37,9 @@ module Selenium
36
37
  caps = process_options(options, capabilities)
37
38
  super(caps: caps, url: url, **opts)
38
39
  @bridge.file_detector = ->((filename, *)) { File.exist?(filename) && filename.to_s }
40
+ command_list = @bridge.command_list
41
+ @bridge.extend(WebDriver::Remote::Features)
42
+ @bridge.add_commands(command_list)
39
43
  end
40
44
 
41
45
  private
@@ -0,0 +1,75 @@
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 Remote
23
+ module Features
24
+ REMOTE_COMMANDS = {
25
+ upload_file: [:post, 'session/:session_id/se/file'],
26
+ get_downloadable_files: [:get, 'session/:session_id/se/files'],
27
+ download_file: [:post, 'session/:session_id/se/files'],
28
+ delete_downloadable_files: [:delete, 'session/:session_id/se/files']
29
+ }.freeze
30
+
31
+ def add_commands(commands)
32
+ @command_list = command_list.merge(commands)
33
+ end
34
+
35
+ def command_list
36
+ @command_list ||= REMOTE_COMMANDS
37
+ end
38
+
39
+ def commands(command)
40
+ command_list[command]
41
+ end
42
+
43
+ def upload(local_file)
44
+ unless File.file?(local_file)
45
+ WebDriver.logger.error("File detector only works with files. #{local_file.inspect} isn`t a file!",
46
+ id: :file_detector)
47
+ raise Error::WebDriverError, "You are trying to upload something that isn't a file."
48
+ end
49
+
50
+ execute :upload_file, {}, {file: Zipper.zip_file(local_file)}
51
+ end
52
+
53
+ def upload_if_necessary(keys)
54
+ local_files = keys.first&.split("\n")&.map { |key| @file_detector.call(Array(key)) }&.compact
55
+ return keys unless local_files&.any?
56
+
57
+ keys = local_files.map { |local_file| upload(local_file) }
58
+ Array(keys.join("\n"))
59
+ end
60
+
61
+ def downloadable_files
62
+ execute :get_downloadable_files
63
+ end
64
+
65
+ def download_file(name)
66
+ execute :download_file, {}, {name: name}
67
+ end
68
+
69
+ def delete_downloadable_files
70
+ execute :delete_downloadable_files
71
+ end
72
+ end
73
+ end # Remote
74
+ end # WebDriver
75
+ end # Selenium
@@ -23,6 +23,7 @@ require 'selenium/webdriver/remote/server_error'
23
23
  module Selenium
24
24
  module WebDriver
25
25
  module Remote
26
+ autoload :Features, 'selenium/webdriver/remote/features'
26
27
  autoload :Bridge, 'selenium/webdriver/remote/bridge'
27
28
  autoload :Driver, 'selenium/webdriver/remote/driver'
28
29
  autoload :Response, 'selenium/webdriver/remote/response'
@@ -28,8 +28,12 @@ module Selenium
28
28
  attach_debugger: [:post, 'session/:session_id/apple/attach_debugger']
29
29
  }.freeze
30
30
 
31
+ def command_list
32
+ SAFARI_COMMANDS.merge(self.class::COMMANDS)
33
+ end
34
+
31
35
  def commands(command)
32
- SAFARI_COMMANDS[command] || self.class::COMMANDS[command]
36
+ command_list[command]
33
37
  end
34
38
 
35
39
  def permissions
@@ -53,7 +53,9 @@ module Selenium
53
53
 
54
54
  case @type
55
55
  when :exclude
56
- "Test not guarded because it breaks test run; #{details}"
56
+ "Test skipped because it breaks test run; #{details}"
57
+ when :flaky
58
+ "Test skipped because it is unreliable in this configuration; #{details}"
57
59
  when :exclusive
58
60
  "Test does not apply to this configuration; #{details}"
59
61
  else
@@ -71,9 +73,10 @@ module Selenium
71
73
  @type == :only
72
74
  end
73
75
 
74
- # Bug is present on all configurations specified, but test can not be run because it breaks other tests
76
+ # Bug is present on all configurations specified, but test can not be run because it breaks other tests,
77
+ # or it is flaky and unreliable
75
78
  def exclude?
76
- @type == :exclude
79
+ @type == :exclude || @type == :flaky
77
80
  end
78
81
 
79
82
  # Test only applies to configurations specified
@@ -24,7 +24,7 @@ module Selenium
24
24
  module WebDriver
25
25
  module Support
26
26
  class Guards
27
- GUARD_TYPES = %i[except only exclude exclusive].freeze
27
+ GUARD_TYPES = %i[except only exclude exclusive flaky].freeze
28
28
 
29
29
  attr_reader :messages
30
30
  attr_accessor :bug_tracker
@@ -19,6 +19,6 @@
19
19
 
20
20
  module Selenium
21
21
  module WebDriver
22
- VERSION = '4.14.0'
22
+ VERSION = '4.15.0'
23
23
  end # WebDriver
24
24
  end # Selenium
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: selenium-webdriver
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.14.0
4
+ version: 4.15.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex Rodionov
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2023-10-10 00:00:00.000000000 Z
13
+ date: 2023-11-01 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rexml
@@ -258,6 +258,7 @@ files:
258
258
  - lib/selenium/webdriver/common/driver_extensions/has_context.rb
259
259
  - lib/selenium/webdriver/common/driver_extensions/has_debugger.rb
260
260
  - lib/selenium/webdriver/common/driver_extensions/has_devtools.rb
261
+ - lib/selenium/webdriver/common/driver_extensions/has_file_downloads.rb
261
262
  - lib/selenium/webdriver/common/driver_extensions/has_launching.rb
262
263
  - lib/selenium/webdriver/common/driver_extensions/has_log_events.rb
263
264
  - lib/selenium/webdriver/common/driver_extensions/has_logs.rb
@@ -348,6 +349,7 @@ files:
348
349
  - lib/selenium/webdriver/firefox/util.rb
349
350
  - lib/selenium/webdriver/ie.rb
350
351
  - lib/selenium/webdriver/ie/driver.rb
352
+ - lib/selenium/webdriver/ie/features.rb
351
353
  - lib/selenium/webdriver/ie/options.rb
352
354
  - lib/selenium/webdriver/ie/service.rb
353
355
  - lib/selenium/webdriver/remote.rb
@@ -355,6 +357,7 @@ files:
355
357
  - lib/selenium/webdriver/remote/bridge/commands.rb
356
358
  - lib/selenium/webdriver/remote/capabilities.rb
357
359
  - lib/selenium/webdriver/remote/driver.rb
360
+ - lib/selenium/webdriver/remote/features.rb
358
361
  - lib/selenium/webdriver/remote/http/common.rb
359
362
  - lib/selenium/webdriver/remote/http/curb.rb
360
363
  - lib/selenium/webdriver/remote/http/default.rb