selenium-webdriver 4.14.0 → 4.16.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 +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
|