selenium-webdriver 4.14.0 → 4.16.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES +29 -1
- data/Gemfile +1 -0
- data/bin/linux/selenium-manager +0 -0
- data/bin/macos/selenium-manager +0 -0
- data/bin/windows/selenium-manager.exe +0 -0
- data/lib/selenium/webdriver/atoms/findElements.js +2 -1
- data/lib/selenium/webdriver/atoms/isDisplayed.js +2 -1
- data/lib/selenium/webdriver/chrome/features.rb +5 -1
- data/lib/selenium/webdriver/chromium/features.rb +0 -4
- data/lib/selenium/webdriver/common/driver_extensions/has_file_downloads.rb +65 -0
- data/lib/selenium/webdriver/common/logger.rb +5 -5
- data/lib/selenium/webdriver/common/options.rb +4 -0
- data/lib/selenium/webdriver/common/platform.rb +4 -0
- data/lib/selenium/webdriver/common/selenium_manager.rb +10 -4
- data/lib/selenium/webdriver/common.rb +1 -0
- data/lib/selenium/webdriver/edge/features.rb +5 -1
- data/lib/selenium/webdriver/firefox/features.rb +5 -1
- data/lib/selenium/webdriver/firefox/profile.rb +3 -1
- data/lib/selenium/webdriver/ie/features.rb +34 -0
- data/lib/selenium/webdriver/ie.rb +4 -3
- data/lib/selenium/webdriver/remote/bridge/commands.rb +0 -6
- data/lib/selenium/webdriver/remote/bridge.rb +1 -20
- data/lib/selenium/webdriver/remote/driver.rb +4 -0
- data/lib/selenium/webdriver/remote/features.rb +75 -0
- data/lib/selenium/webdriver/remote.rb +1 -0
- data/lib/selenium/webdriver/safari/features.rb +5 -1
- data/lib/selenium/webdriver/support/event_firing_bridge.rb +2 -2
- data/lib/selenium/webdriver/support/guards/guard.rb +6 -3
- data/lib/selenium/webdriver/support/guards.rb +1 -1
- data/lib/selenium/webdriver/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7638be962a9b81fc47c44f342971675991879878eb23c46d7f8108e944adc054
|
4
|
+
data.tar.gz: 1b0cdd4f1d70fa58950549d92750d1d2836143418c42a868e7809e496f56726e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5247d707dc2b479973da7154b2bf96c9fefa9f134e56de8ed53fa596345c54a4c249debf357d6bcbc07eb000204bf1e8b4e031c02bb10bc110e346afbf0bf3af
|
7
|
+
data.tar.gz: af60275e2063f0ac2247b91bb148b45df2164b02893aeb7a2f21bda8def67d3c95ea620c58f04d5e8faa2561326afbe56903f23b4ff02686c80c84bda0b8746c
|
data/CHANGES
CHANGED
@@ -1,4 +1,32 @@
|
|
1
|
-
4.
|
1
|
+
4.16.0 (unreleased)
|
2
|
+
=========================
|
3
|
+
|
4
|
+
Ruby:
|
5
|
+
* Add RBS files to Ruby (#12844)
|
6
|
+
* Convert binary locations for cygwin (#12618)
|
7
|
+
* Allow Selenium Manager to work with Unix (#13161)
|
8
|
+
* Extend RBS support for logger and log entry (#13192)
|
9
|
+
* Update rules_ruby to the latest version (#13235)
|
10
|
+
|
11
|
+
BiDi:
|
12
|
+
* Released selenium-devtools 0.120.0 (supports CDP v85, v118, v119, v120)
|
13
|
+
|
14
|
+
Chrome:
|
15
|
+
* Fix http proxy configuration for chrome (#13093)
|
16
|
+
|
17
|
+
Firefox:
|
18
|
+
* Delete 'lock' file in FF profile (#13090)
|
19
|
+
|
20
|
+
4.15.0 (2023-11-01)
|
21
|
+
=========================
|
22
|
+
|
23
|
+
* Do not set browser binary in selenium manager if it is an empty string (#12738)
|
24
|
+
* Add flaky condition to guards to mark unreliable tests
|
25
|
+
* Rake update needs to build latest grid for running remote tests
|
26
|
+
* Add CDP v119 and remove v116
|
27
|
+
* Implement file downloads (#12979)
|
28
|
+
|
29
|
+
4.14.0 (2023-10-09)
|
2
30
|
=========================
|
3
31
|
Ruby:
|
4
32
|
* allow users to access the full script of the atom directly
|
data/Gemfile
CHANGED
data/bin/linux/selenium-manager
CHANGED
Binary file
|
data/bin/macos/selenium-manager
CHANGED
Binary file
|
Binary file
|
@@ -97,7 +97,8 @@ Number(d[1]),c=Number(d[2]),d=Number(d[3]),0<=b&&255>=b&&0<=c&&255>=c&&0<=d&&255
|
|
97
97
|
function $c(a,b){var c=a.currentStyle||a.style,d=c[b];void 0===d&&ea(c.getPropertyValue)&&(d=c.getPropertyValue(b));return"inherit"!=d?void 0!==d?d:null:(a=Zc(a))?$c(a,b):null}
|
98
98
|
function ad(a,b,c){function d(g){var h=W(g);return 0<h.height&&0<h.width?!0:S(g,"PATH")&&(0<h.height||0<h.width)?(g=V(g,"stroke-width"),!!g&&0<parseInt(g,10)):"hidden"!=V(g,"overflow")&&sa(g.childNodes,function(n){return 3==n.nodeType||S(n)&&d(n)})}function e(g){return bd(g)==X&&ta(g.childNodes,function(h){return!S(h)||e(h)||!d(h)})}if(!S(a))throw Error("Argument to isShown must be of type Element");if(S(a,"BODY"))return!0;if(S(a,"OPTION")||S(a,"OPTGROUP"))return a=lb(a,function(g){return S(g,"SELECT")}),
|
99
99
|
!!a&&ad(a,!0,c);var f=cd(a);if(f)return!!f.image&&0<f.rect.width&&0<f.rect.height&&ad(f.image,b,c);if(S(a,"INPUT")&&"hidden"==a.type.toLowerCase()||S(a,"NOSCRIPT"))return!1;f=V(a,"visibility");return"collapse"!=f&&"hidden"!=f&&c(a)&&(b||0!=dd(a))&&d(a)?!e(a):!1}
|
100
|
-
function ed(a){function b(c){if(S(c)&&"none"==V(c,"display"))return!1;var d;if((d=c.parentNode)&&d.shadowRoot&&void 0!==c.assignedSlot)d=c.assignedSlot?c.assignedSlot.parentNode:null;else if(c.getDestinationInsertionPoints){var e=c.getDestinationInsertionPoints();0<e.length&&(d=e[e.length-1])}if(Yc&&d instanceof ShadowRoot){if(d.host.shadowRoot!==d)return!1;d=d.host}return!d||9!=d.nodeType&&11!=d.nodeType?d&&S(d,"DETAILS")&&!d.open&&!S(c,"SUMMARY")?!1:!!d&&b(d):!0}return ad(a,!1,
|
100
|
+
function ed(a){function b(c){if(S(c)&&"none"==V(c,"display"))return!1;var d;if((d=c.parentNode)&&d.shadowRoot&&void 0!==c.assignedSlot)d=c.assignedSlot?c.assignedSlot.parentNode:null;else if(c.getDestinationInsertionPoints){var e=c.getDestinationInsertionPoints();0<e.length&&(d=e[e.length-1])}if(Yc&&d instanceof ShadowRoot){if(d.host.shadowRoot&&d.host.shadowRoot!==d)return!1;d=d.host}return!d||9!=d.nodeType&&11!=d.nodeType?d&&S(d,"DETAILS")&&!d.open&&!S(c,"SUMMARY")?!1:!!d&&b(d):!0}return ad(a,!1,
|
101
|
+
b)}var X="hidden";
|
101
102
|
function bd(a){function b(m){function v(Ab){if(Ab==g)return!0;var pc=V(Ab,"display");return 0==pc.lastIndexOf("inline",0)||"contents"==pc||"absolute"==qc&&"static"==V(Ab,"position")?!1:!0}var qc=V(m,"position");if("fixed"==qc)return u=!0,m==g?null:g;for(m=Zc(m);m&&!v(m);)m=Zc(m);return m}function c(m){var v=m;if("visible"==n)if(m==g&&h)v=h;else if(m==h)return{x:"visible",y:"visible"};v={x:V(v,"overflow-x"),y:V(v,"overflow-y")};m==g&&(v.x="visible"==v.x?"auto":v.x,v.y="visible"==v.y?"auto":v.y);return v}
|
102
103
|
function d(m){if(m==g){var v=(new fb(f)).a;m=v.scrollingElement?v.scrollingElement:Oa||"CSS1Compat"!=v.compatMode?v.body||v.documentElement:v.documentElement;v=v.parentWindow||v.defaultView;m=t&&Ua("10")&&v.pageYOffset!=m.scrollTop?new cb(m.scrollLeft,m.scrollTop):new cb(v.pageXOffset||m.scrollLeft,v.pageYOffset||m.scrollTop)}else m=new cb(m.scrollLeft,m.scrollTop);return m}var e=fd(a),f=A(a),g=f.documentElement,h=f.body,n=V(g,"overflow"),u;for(a=b(a);a;a=b(a)){var p=c(a);if("visible"!=p.x||"visible"!=
|
103
104
|
p.y){var G=W(a);if(0==G.width||0==G.height)return X;var R=e.a<G.a,fa=e.b<G.b;if(R&&"hidden"==p.x||fa&&"hidden"==p.y)return X;if(R&&"visible"!=p.x||fa&&"visible"!=p.y){R=d(a);fa=e.b<G.b-R.y;if(e.a<G.a-R.x&&"visible"!=p.x||fa&&"visible"!=p.x)return X;e=bd(a);return e==X?X:"scroll"}R=e.f>=G.a+G.width;G=e.c>=G.b+G.height;if(R&&"hidden"==p.x||G&&"hidden"==p.y)return X;if(R&&"visible"!=p.x||G&&"visible"!=p.y){if(u&&(p=d(a),e.f>=g.scrollWidth-p.x||e.a>=g.scrollHeight-p.y))return X;e=bd(a);return e==X?X:
|
@@ -97,4 +97,5 @@ r.y){var D=Jc(a);if(0==D.width||0==D.height)return Z;var L=e.a<D.a,M=e.b<D.b;if(
|
|
97
97
|
function Jc(a){var b=Lc(a);if(b)return b.rect;if(W(a,"HTML"))return a=A(a),a=((a?a.parentWindow||a.defaultView:window)||window).document,a="CSS1Compat"==a.compatMode?a.documentElement:a.body,a=new Va(a.clientWidth,a.clientHeight),new X(0,0,a.width,a.height);try{var c=a.getBoundingClientRect()}catch(d){return new X(0,0,0,0)}b=new X(c.left,c.top,c.right-c.left,c.bottom-c.top);v&&a.ownerDocument.body&&(a=A(a),b.a-=a.documentElement.clientLeft+a.body.clientLeft,b.b-=a.documentElement.clientTop+a.body.clientTop);
|
98
98
|
return b}function Lc(a){var b=W(a,"MAP");if(!b&&!W(a,"AREA"))return null;var c=b?a:W(a.parentNode,"MAP")?a.parentNode:null,d=null,e=null;c&&c.name&&(d=Dc('/descendant::*[@usemap = "#'+c.name+'"]',A(c)))&&(e=Jc(d),b||"default"==a.shape.toLowerCase()||(a=Oc(a),b=Math.min(Math.max(a.a,0),e.width),c=Math.min(Math.max(a.b,0),e.height),e=new X(b+e.a,c+e.b,Math.min(a.width,e.width-b),Math.min(a.height,e.height-c))));return{image:d,rect:e||new X(0,0,0,0)}}
|
99
99
|
function Oc(a){var b=a.shape.toLowerCase();a=a.coords.split(",");if("rect"==b&&4==a.length){b=a[0];var c=a[1];return new X(b,c,a[2]-b,a[3]-c)}if("circle"==b&&3==a.length)return b=a[2],new X(a[0]-b,a[1]-b,2*b,2*b);if("poly"==b&&2<a.length){b=a[0];c=a[1];for(var d=b,e=c,f=2;f+1<a.length;f+=2)b=Math.min(b,a[f]),d=Math.max(d,a[f]),c=Math.min(c,a[f+1]),e=Math.max(e,a[f+1]);return new X(b,c,d-b,e-c)}return new X(0,0,0,0)}function Nc(a){a=Jc(a);return new Ec(a.b,a.a+a.width,a.b+a.height,a.a)}
|
100
|
-
function Mc(a){if(Ac){if("relative"==Y(a,"position"))return 1;a=Y(a,"filter");return(a=a.match(/^alpha\(opacity=(\d*)\)/)||a.match(/^progid:DXImageTransform.Microsoft.Alpha\(Opacity=(\d*)\)/))?Number(a[1])/100:1}return Pc(a)}function Pc(a){var b=1,c=Y(a,"opacity");c&&(b=Number(c));(a=Gc(a))&&(b*=Pc(a));return b};ba("_",function(a,b){function c(d){if(W(d)&&"none"==Y(d,"display"))return!1;var e;if((e=d.parentNode)&&e.shadowRoot&&void 0!==d.assignedSlot)e=d.assignedSlot?d.assignedSlot.parentNode:null;else if(d.getDestinationInsertionPoints){var f=d.getDestinationInsertionPoints();0<f.length&&(e=f[f.length-1])}if(Fc&&e instanceof ShadowRoot){if(e.host.shadowRoot!==e)return!1;e=e.host}return!e||9!=e.nodeType&&11!=e.nodeType?e&&W(e,"DETAILS")&&!e.open&&!W(d,"SUMMARY")?!1:!!e&&c(e):!0}return Ic(a
|
100
|
+
function Mc(a){if(Ac){if("relative"==Y(a,"position"))return 1;a=Y(a,"filter");return(a=a.match(/^alpha\(opacity=(\d*)\)/)||a.match(/^progid:DXImageTransform.Microsoft.Alpha\(Opacity=(\d*)\)/))?Number(a[1])/100:1}return Pc(a)}function Pc(a){var b=1,c=Y(a,"opacity");c&&(b=Number(c));(a=Gc(a))&&(b*=Pc(a));return b};ba("_",function(a,b){function c(d){if(W(d)&&"none"==Y(d,"display"))return!1;var e;if((e=d.parentNode)&&e.shadowRoot&&void 0!==d.assignedSlot)e=d.assignedSlot?d.assignedSlot.parentNode:null;else if(d.getDestinationInsertionPoints){var f=d.getDestinationInsertionPoints();0<f.length&&(e=f[f.length-1])}if(Fc&&e instanceof ShadowRoot){if(e.host.shadowRoot&&e.host.shadowRoot!==e)return!1;e=e.host}return!e||9!=e.nodeType&&11!=e.nodeType?e&&W(e,"DETAILS")&&!e.open&&!W(d,"SUMMARY")?!1:!!e&&c(e):!0}return Ic(a,
|
101
|
+
!!b,c)});; return this._.apply(null,arguments);}).apply({navigator:typeof window!='undefined'?window.navigator:null,document:typeof window!='undefined'?window.document:null}, arguments);}
|
@@ -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
|
-
|
43
|
+
command_list[command]
|
40
44
|
end
|
41
45
|
end # Bridge
|
42
46
|
end # Chrome
|
@@ -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
|
@@ -103,7 +103,7 @@ module Selenium
|
|
103
103
|
#
|
104
104
|
# @param [Array, Symbol] ids
|
105
105
|
#
|
106
|
-
def allow(ids)
|
106
|
+
def allow(*ids)
|
107
107
|
@allowed += Array(ids).flatten
|
108
108
|
end
|
109
109
|
|
@@ -112,7 +112,7 @@ module Selenium
|
|
112
112
|
# Overrides default #debug to skip ignored messages by provided id
|
113
113
|
#
|
114
114
|
# @param [String] message
|
115
|
-
# @param [Symbol, Array<
|
115
|
+
# @param [Symbol, Array<Symbol>] id
|
116
116
|
# @yield see #deprecate
|
117
117
|
#
|
118
118
|
def debug(message, id: [], &block)
|
@@ -123,7 +123,7 @@ module Selenium
|
|
123
123
|
# Used to supply information of general interest
|
124
124
|
#
|
125
125
|
# @param [String] message
|
126
|
-
# @param [Symbol, Array<
|
126
|
+
# @param [Symbol, Array<Symbol>] id
|
127
127
|
# @yield see #deprecate
|
128
128
|
#
|
129
129
|
def info(message, id: [], &block)
|
@@ -134,7 +134,7 @@ module Selenium
|
|
134
134
|
# Used to supply information that suggests an error occurred
|
135
135
|
#
|
136
136
|
# @param [String] message
|
137
|
-
# @param [Symbol, Array<
|
137
|
+
# @param [Symbol, Array<Symbol>] id
|
138
138
|
# @yield see #deprecate
|
139
139
|
#
|
140
140
|
def error(message, id: [], &block)
|
@@ -145,7 +145,7 @@ module Selenium
|
|
145
145
|
# Used to supply information that suggests action be taken by user
|
146
146
|
#
|
147
147
|
# @param [String] message
|
148
|
-
# @param [Symbol, Array<
|
148
|
+
# @param [Symbol, Array<Symbol>] id
|
149
149
|
# @yield see #deprecate
|
150
150
|
#
|
151
151
|
def warn(message, id: [], &block)
|
@@ -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|
|
@@ -41,11 +41,11 @@ module Selenium
|
|
41
41
|
|
42
42
|
output = run(*command)
|
43
43
|
|
44
|
-
browser_path = output['browser_path']
|
45
|
-
driver_path = output['driver_path']
|
44
|
+
browser_path = Platform.cygwin? ? Platform.cygwin_path(output['browser_path']) : output['browser_path']
|
45
|
+
driver_path = Platform.cygwin? ? Platform.cygwin_path(output['driver_path']) : output['driver_path']
|
46
46
|
Platform.assert_executable driver_path
|
47
47
|
|
48
|
-
if options.respond_to?
|
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
|
@@ -67,7 +67,7 @@ module Selenium
|
|
67
67
|
end
|
68
68
|
if options.proxy
|
69
69
|
command << '--proxy'
|
70
|
-
|
70
|
+
command << (options.proxy.ssl || options.proxy.http)
|
71
71
|
end
|
72
72
|
command
|
73
73
|
end
|
@@ -83,7 +83,13 @@ module Selenium
|
|
83
83
|
"#{directory}/macos/selenium-manager"
|
84
84
|
elsif Platform.linux?
|
85
85
|
"#{directory}/linux/selenium-manager"
|
86
|
+
elsif Platform.unix?
|
87
|
+
WebDriver.logger.warn('Selenium Manager binary may not be compatible with Unix; verify settings',
|
88
|
+
id: %i[selenium_manager unix_binary])
|
89
|
+
"#{directory}/linux/selenium-manager"
|
86
90
|
end
|
91
|
+
rescue Error::WebDriverError => e
|
92
|
+
raise Error::WebDriverError, "Unable to obtain Selenium Manager binary for #{e.message}"
|
87
93
|
end)
|
88
94
|
|
89
95
|
validate_location(location)
|
@@ -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
|
-
|
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
|
-
|
37
|
+
command_list[command]
|
34
38
|
end
|
35
39
|
|
36
40
|
def install_addon(path, temporary)
|
@@ -33,6 +33,8 @@ module Selenium
|
|
33
33
|
'security.csp.enable' => false
|
34
34
|
}.freeze
|
35
35
|
|
36
|
+
LOCK_FILES = %w[.parentlock parent.lock lock].freeze
|
37
|
+
|
36
38
|
attr_reader :name, :log_file
|
37
39
|
attr_writer :secure_ssl, :load_no_focus_lib
|
38
40
|
|
@@ -176,7 +178,7 @@ module Selenium
|
|
176
178
|
end
|
177
179
|
|
178
180
|
def delete_lock_files(directory)
|
179
|
-
|
181
|
+
LOCK_FILES.each do |name|
|
180
182
|
FileUtils.rm_f File.join(directory, name)
|
181
183
|
end
|
182
184
|
end
|
@@ -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 :
|
24
|
-
autoload :
|
25
|
-
autoload :
|
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
|
-
|
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
|
-
|
36
|
+
command_list[command]
|
33
37
|
end
|
34
38
|
|
35
39
|
def permissions
|
@@ -120,8 +120,8 @@ module Selenium
|
|
120
120
|
returned
|
121
121
|
end
|
122
122
|
|
123
|
-
def method_missing(meth,
|
124
|
-
@delegate.__send__(meth,
|
123
|
+
def method_missing(meth, ...) # rubocop:disable Style/MissingRespondToMissing
|
124
|
+
@delegate.__send__(meth, ...)
|
125
125
|
end
|
126
126
|
end # EventFiringBridge
|
127
127
|
end # Support
|
@@ -53,7 +53,9 @@ module Selenium
|
|
53
53
|
|
54
54
|
case @type
|
55
55
|
when :exclude
|
56
|
-
"Test
|
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
|
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.
|
4
|
+
version: 4.16.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-
|
13
|
+
date: 2023-12-06 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
|