selenium-webdriver 4.9.1 → 4.11.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 +27 -0
- data/README.md +1 -1
- 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/server.rb +4 -16
- data/lib/selenium/webdriver/atoms/findElements.js +3 -4
- data/lib/selenium/webdriver/chrome/service.rb +1 -3
- data/lib/selenium/webdriver/chromium/options.rb +0 -18
- data/lib/selenium/webdriver/chromium.rb +0 -1
- data/lib/selenium/webdriver/common/child_process.rb +2 -2
- data/lib/selenium/webdriver/common/driver_finder.rb +10 -9
- data/lib/selenium/webdriver/common/error.rb +28 -3
- data/lib/selenium/webdriver/common/logger.rb +21 -8
- data/lib/selenium/webdriver/common/options.rb +3 -22
- data/lib/selenium/webdriver/common/platform.rb +0 -49
- data/lib/selenium/webdriver/common/proxy.rb +1 -1
- data/lib/selenium/webdriver/common/selenium_manager.rb +49 -26
- data/lib/selenium/webdriver/common/service.rb +1 -11
- data/lib/selenium/webdriver/common/websocket_connection.rb +1 -1
- data/lib/selenium/webdriver/edge/options.rb +14 -0
- data/lib/selenium/webdriver/edge/service.rb +1 -3
- data/lib/selenium/webdriver/firefox/options.rb +0 -15
- data/lib/selenium/webdriver/firefox/service.rb +0 -12
- data/lib/selenium/webdriver/ie/options.rb +2 -1
- data/lib/selenium/webdriver/ie/service.rb +0 -16
- data/lib/selenium/webdriver/remote/capabilities.rb +0 -72
- data/lib/selenium/webdriver/remote/http/default.rb +1 -2
- data/lib/selenium/webdriver/remote/server_error.rb +1 -1
- data/lib/selenium/webdriver/safari/service.rb +10 -0
- data/lib/selenium/webdriver/version.rb +1 -1
- data/selenium-webdriver.gemspec +1 -0
- metadata +16 -3
- data/lib/selenium/webdriver/chromium/service.rb +0 -42
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 55c2b164be56b90064957852c6b1f890f9cda063d5c0ef164752b7c67f6e40bb
         | 
| 4 | 
            +
              data.tar.gz: 778d0c6d2450a3d178d709762c76b9ef2c24832131d4487f6c84b5789a32b1de
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 6777b04b259f2e7be27d7c2635f77b0e9006464f931e1e79a1e10f517474b71344534a8b02ba84445801581f4c50cb79901d15ef8e74133c08357625e5ad9de6
         | 
| 7 | 
            +
              data.tar.gz: 5f1e3af40a4bbcc3e4e77407321d64b1e6920ca91fcf7605bce780d42138fd587bfc951563205d8cf6e4b63952e7e4e35dd52aba496fcb1e468e6a086c81c92d
         | 
    
        data/CHANGES
    CHANGED
    
    | @@ -1,3 +1,30 @@ | |
| 1 | 
            +
            4.11.0 (2023-07-31)
         | 
| 2 | 
            +
            =========================
         | 
| 3 | 
            +
            Ruby:
         | 
| 4 | 
            +
              * Made network interception threads fail silently (#12226)
         | 
| 5 | 
            +
              * Have Selenium Manager binary locate drivers on PATH (#12345)
         | 
| 6 | 
            +
              * Add browser output from selenium manager to options (#12398)
         | 
| 7 | 
            +
              * Remove deprecated code (#12417)
         | 
| 8 | 
            +
            BiDi:
         | 
| 9 | 
            +
              * Released selenium-devtools 0.115.0 (supports CDP v85, v113, v114, v115)
         | 
| 10 | 
            +
            Edge:
         | 
| 11 | 
            +
              * Adding ignore process match for IE Mode across bindings (#12279)
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            4.10.0 (2023-06-07)
         | 
| 14 | 
            +
            =========================
         | 
| 15 | 
            +
            Ruby:
         | 
| 16 | 
            +
              * Implement proxy support for Selenium Manager
         | 
| 17 | 
            +
              * Prevent setting driver log level in Safari
         | 
| 18 | 
            +
              * Change all Selenium Manager logging to :debug (#12145)
         | 
| 19 | 
            +
              * Error messages include links to documentation
         | 
| 20 | 
            +
              * Add custom error class for driver location and improve error logic
         | 
| 21 | 
            +
             | 
| 22 | 
            +
            BiDi:
         | 
| 23 | 
            +
              * Released selenium-devtools 0.114.0 (supports CDP v85, v112, v113, v114)
         | 
| 24 | 
            +
             | 
| 25 | 
            +
            Edge:
         | 
| 26 | 
            +
              * Add support for webview2
         | 
| 27 | 
            +
             | 
| 1 28 | 
             
            4.9.1 (2023-05-08)
         | 
| 2 29 | 
             
            =========================
         | 
| 3 30 | 
             
            Ruby:
         | 
    
        data/README.md
    CHANGED
    
    | @@ -15,7 +15,7 @@ This gem provides Ruby bindings for Selenium and supports MRI >= 3.0. | |
| 15 15 |  | 
| 16 16 | 
             
            ## License
         | 
| 17 17 |  | 
| 18 | 
            -
            Copyright 2009- | 
| 18 | 
            +
            Copyright 2009-2023 Software Freedom Conservancy
         | 
| 19 19 |  | 
| 20 20 | 
             
            Licensed to the Software Freedom Conservancy (SFC) under one
         | 
| 21 21 | 
             
            or more contributor license agreements.  See the NOTICE file
         | 
    
        data/bin/linux/selenium-manager
    CHANGED
    
    | Binary file | 
    
        data/bin/macos/selenium-manager
    CHANGED
    
    | Binary file | 
| Binary file | 
    
        data/lib/selenium/server.rb
    CHANGED
    
    | @@ -18,6 +18,7 @@ | |
| 18 18 | 
             
            # under the License.
         | 
| 19 19 |  | 
| 20 20 | 
             
            require 'selenium/webdriver/common/child_process'
         | 
| 21 | 
            +
            require 'selenium/webdriver/common/port_prober'
         | 
| 21 22 | 
             
            require 'selenium/webdriver/common/socket_poller'
         | 
| 22 23 | 
             
            require 'net/http'
         | 
| 23 24 |  | 
| @@ -165,7 +166,7 @@ module Selenium | |
| 165 166 | 
             
                # :standalone, #hub, #node
         | 
| 166 167 | 
             
                #
         | 
| 167 168 |  | 
| 168 | 
            -
                attr_accessor :role, :port, :timeout, :background, :log
         | 
| 169 | 
            +
                attr_accessor :role, :host, :port, :timeout, :background, :log
         | 
| 169 170 |  | 
| 170 171 | 
             
                #
         | 
| 171 172 | 
             
                # @param [String] jar Path to the server jar.
         | 
| @@ -185,7 +186,7 @@ module Selenium | |
| 185 186 | 
             
                  @jar = jar
         | 
| 186 187 | 
             
                  @host = '127.0.0.1'
         | 
| 187 188 | 
             
                  @role = opts.fetch(:role, 'standalone')
         | 
| 188 | 
            -
                  @port = opts.fetch(:port, 4444)
         | 
| 189 | 
            +
                  @port = opts.fetch(:port, WebDriver::PortProber.above(4444))
         | 
| 189 190 | 
             
                  @timeout = opts.fetch(:timeout, 30)
         | 
| 190 191 | 
             
                  @background = opts.fetch(:background, false)
         | 
| 191 192 | 
             
                  @additional_args = opts.fetch(:args, [])
         | 
| @@ -207,12 +208,6 @@ module Selenium | |
| 207 208 | 
             
                end
         | 
| 208 209 |  | 
| 209 210 | 
             
                def stop
         | 
| 210 | 
            -
                  begin
         | 
| 211 | 
            -
                    Net::HTTP.get(@host, '/selenium-server/driver/?cmd=shutDownSeleniumServer', @port)
         | 
| 212 | 
            -
                  rescue Errno::ECONNREFUSED
         | 
| 213 | 
            -
                    nil
         | 
| 214 | 
            -
                  end
         | 
| 215 | 
            -
             | 
| 216 211 | 
             
                  stop_process if @process
         | 
| 217 212 | 
             
                  poll_for_shutdown
         | 
| 218 213 |  | 
| @@ -234,13 +229,7 @@ module Selenium | |
| 234 229 | 
             
                private
         | 
| 235 230 |  | 
| 236 231 | 
             
                def stop_process
         | 
| 237 | 
            -
                   | 
| 238 | 
            -
             | 
| 239 | 
            -
                  begin
         | 
| 240 | 
            -
                    @process.poll_for_exit(5)
         | 
| 241 | 
            -
                  rescue WebDriver::ChildProcess::TimeoutError
         | 
| 242 | 
            -
                    @process.stop
         | 
| 243 | 
            -
                  end
         | 
| 232 | 
            +
                  @process.stop
         | 
| 244 233 | 
             
                rescue Errno::ECHILD
         | 
| 245 234 | 
             
                  # already dead
         | 
| 246 235 | 
             
                ensure
         | 
| @@ -254,7 +243,6 @@ module Selenium | |
| 254 243 | 
             
                    args = ['-jar', @jar, @role, '--port', @port.to_s]
         | 
| 255 244 | 
             
                    server_command = ['java'] + properties + args + @additional_args
         | 
| 256 245 | 
             
                    cp = WebDriver::ChildProcess.build(*server_command)
         | 
| 257 | 
            -
                    WebDriver.logger.debug("Executing Process #{server_command}", id: :server)
         | 
| 258 246 |  | 
| 259 247 | 
             
                    if @log.is_a?(String)
         | 
| 260 248 | 
             
                      cp.io = @log
         | 
| @@ -113,10 +113,9 @@ function nd(a,b,c,d){a=a.nodeValue.replace(/[\u200b\u200e\u200f]/g,"");a=a.repla | |
| 113 113 | 
             
            function pd(a,b,c,d,e){if(3==a.nodeType&&c)nd(a,b,d,e);else if(S(a))if(S(a,"CONTENT")||S(a,"SLOT")){for(var f=a;f.parentNode;)f=f.parentNode;f instanceof ShadowRoot?(a=S(a,"CONTENT")?a.getDistributedNodes():a.assignedNodes(),l(a,function(g){pd(g,b,c,d,e)})):jd(a,b)}else if(S(a,"SHADOW")){for(f=a;f.parentNode;)f=f.parentNode;if(f instanceof ShadowRoot&&(a=f))for(a=a.olderShadowRoot;a;)l(a.childNodes,function(g){pd(g,b,c,d,e)}),a=a.olderShadowRoot}else jd(a,b)}
         | 
| 114 114 | 
             
            function jd(a,b){a.shadowRoot&&l(a.shadowRoot.childNodes,function(c){pd(c,b,!0,null,null)});ld(a,b,function(c,d,e,f,g){var h=null;1==c.nodeType?h=c:3==c.nodeType&&(h=c);null!=h&&(null!=h.assignedSlot||h.getDestinationInsertionPoints&&0<h.getDestinationInsertionPoints().length)||pd(c,d,e,f,g)})};var qd={C:function(a,b){return!(!a.querySelectorAll||!a.querySelector)&&!/^\d.*/.test(b)},o:function(a,b){var c=eb(b),d="string"===typeof a?c.a.getElementById(a):a;return d?Uc(d,"id")==a&&b!=d&&hb(b,d)?d:ua(mb(c,"*"),function(e){return Uc(e,"id")==a&&b!=e&&hb(b,e)}):null},j:function(a,b){if(!a)return[];if(qd.C(b,a))try{return b.querySelectorAll("#"+qd.T(a))}catch(c){return[]}b=mb(eb(b),"*",null,b);return pa(b,function(c){return Uc(c,"id")==a})},T:function(a){return a.replace(/([\s'"\\#.:;,!?+<>=~*^$|%&@`{}\-\/\[\]\(\)])/g,
         | 
| 115 115 | 
             
            "\\$1")}};var Y={},rd={};Y.N=function(a,b,c){try{var d=Nc.j("a",b)}catch(e){d=mb(eb(b),"A",null,b)}return ua(d,function(e){e=id(e);e=e.replace(/^[\s]+|[\s]+$/g,"");return c&&-1!=e.indexOf(a)||e==a})};Y.K=function(a,b,c){try{var d=Nc.j("a",b)}catch(e){d=mb(eb(b),"A",null,b)}return pa(d,function(e){e=id(e);e=e.replace(/^[\s]+|[\s]+$/g,"");return c&&-1!=e.indexOf(a)||e==a})};Y.o=function(a,b){return Y.N(a,b,!1)};Y.j=function(a,b){return Y.K(a,b,!1)};rd.o=function(a,b){return Y.N(a,b,!0)};
         | 
| 116 | 
            -
            rd.j=function(a,b){return Y.K(a,b,!0)};var Z={F:function(a,b){return function(c){var d=Z.u(a);d=W(d);c=W(c);return b.call(null,d,c)}},R:function(a){return Z.F(a,function(b,c){return c.b+c.height<b.b})},S:function(a){return Z.F(a,function(b,c){return b.b+b.height<c.b})},V:function(a){return Z.F(a,function(b,c){return c.a+c.width<b.a})},aa:function(a){return Z.F(a,function(b,c){return b.a+b.width<c.a})},W:function(a,b){var c;b?c=b:"number"==typeof a.distance&&(c=a.distance);c||(c= | 
| 117 | 
            -
             | 
| 118 | 
            -
             | 
| 119 | 
            -
            Z.U=function(a,b){var c=[];l(a,function(e){e&&ta(b,function(f){var g=f.kind,h=Z.P[g];if(!h)throw new P(61,"Cannot find filter suitable for "+g);return h.apply(null,f.args)(e)},null)&&c.push(e)},null);a=b[b.length-1];var d=Z.O[a?a.kind:"unknown"];return d?(a=d.apply(null,a.args))?Z.ba(a,c):c:c};
         | 
| 116 | 
            +
            rd.j=function(a,b){return Y.K(a,b,!0)};var Z={F:function(a,b){return function(c){var d=Z.u(a);d=W(d);c=W(c);return b.call(null,d,c)}},R:function(a){return Z.F(a,function(b,c){return c.b+c.height<b.b})},S:function(a){return Z.F(a,function(b,c){return b.b+b.height<c.b})},V:function(a){return Z.F(a,function(b,c){return c.a+c.width<b.a})},aa:function(a){return Z.F(a,function(b,c){return b.a+b.width<c.a})},W:function(a,b){var c;b?c=b:"number"==typeof a.distance&&(c=a.distance);c||(c=50);return function(d){var e=Z.u(a);if(e===d)return!1;e=W(e);
         | 
| 117 | 
            +
            d=W(d);e=new U(e.a-c,e.b-c,e.width+2*c,e.height+2*c);return e.a<=d.a+d.width&&d.a<=e.a+e.width&&e.b<=d.b+d.height&&d.b<=e.b+e.height}},u:function(a){if(ha(a)&&1==a.nodeType)return a;if(ea(a))return Z.u(a.call(null));if(ha(a)){var b;a:{if(b=sd(a)){var c=td[b];if(c&&ea(c.o)){b=c.o(a[b],Bc.document);break a}}throw new P(61,"Unsupported locator strategy: "+b);}if(!b)throw new P(7,"No element has been found by "+JSON.stringify(a));return b}throw new P(61,"Selector is of wrong type: "+JSON.stringify(a));
         | 
| 118 | 
            +
            }};Z.P={left:Z.V,right:Z.aa,above:Z.R,below:Z.S,near:Z.W};Z.O={left:Z.u,right:Z.u,above:Z.u,below:Z.u,near:Z.u};Z.U=function(a,b){var c=[];l(a,function(e){e&&ta(b,function(f){var g=f.kind,h=Z.P[g];if(!h)throw new P(61,"Cannot find filter suitable for "+g);return h.apply(null,f.args)(e)},null)&&c.push(e)},null);a=b[b.length-1];var d=Z.O[a?a.kind:"unknown"];return d?(a=d.apply(null,a.args))?Z.ba(a,c):c:c};
         | 
| 120 119 | 
             
            Z.ba=function(a,b){function c(f){f=W(f);return Math.sqrt(Math.pow(d-(f.a+Math.max(1,f.width)/2),2)+Math.pow(e-(f.b+Math.max(1,f.height)/2),2))}a=W(a);var d=a.a+Math.max(1,a.width)/2,e=a.b+Math.max(1,a.height)/2;xa(b,function(f,g){return c(f)-c(g)});return b};Z.o=function(a,b){a=Z.j(a,b);return 0==a.length?null:a[0]};
         | 
| 121 120 | 
             
            Z.j=function(a,b){if(!a.hasOwnProperty("root")||!a.hasOwnProperty("filters"))throw new P(61,"Locator not suitable for relative locators: "+JSON.stringify(a));var c=a.filters,d=da(c);if("array"!=d&&("object"!=d||"number"!=typeof c.length))throw new P(61,"Targets should be an array: "+JSON.stringify(a));var e;S(a.root)?e=[a.root]:e=ud(a.root,b);return 0==e.length?[]:Z.U(e,a.filters)};var vd={o:function(a,b){if(""===a)throw new P(32,'Unable to locate an element with the tagName ""');return b.getElementsByTagName(a)[0]||null},j:function(a,b){if(""===a)throw new P(32,'Unable to locate an element with the tagName ""');return b.getElementsByTagName(a)}};var td={className:Dc,"class name":Dc,css:Nc,"css selector":Nc,relative:Z,id:qd,linkText:Y,"link text":Y,name:{o:function(a,b){b=mb(eb(b),"*",null,b);return ua(b,function(c){return Uc(c,"name")==a})},j:function(a,b){b=mb(eb(b),"*",null,b);return pa(b,function(c){return Uc(c,"name")==a})}},partialLinkText:rd,"partial link text":rd,tagName:vd,"tag name":vd,xpath:T};function sd(a){for(var b in a)if(a.hasOwnProperty(b))return b;return null}
         | 
| 122 121 | 
             
            function ud(a,b){var c=sd(a);if(c){var d=td[c];if(d&&ea(d.j))return d.j(a[c],b||Bc.document)}throw new P(61,"Unsupported locator strategy: "+c);};ca("_",ud);; return this._.apply(null,arguments);}).apply({navigator:typeof window!='undefined'?window.navigator:null,document:typeof window!='undefined'?window.document:null}, arguments);}
         | 
| @@ -17,12 +17,10 @@ | |
| 17 17 | 
             
            # specific language governing permissions and limitations
         | 
| 18 18 | 
             
            # under the License.
         | 
| 19 19 |  | 
| 20 | 
            -
            require 'selenium/webdriver/chromium/service'
         | 
| 21 | 
            -
             | 
| 22 20 | 
             
            module Selenium
         | 
| 23 21 | 
             
              module WebDriver
         | 
| 24 22 | 
             
                module Chrome
         | 
| 25 | 
            -
                  class Service <  | 
| 23 | 
            +
                  class Service < WebDriver::Service
         | 
| 26 24 | 
             
                    DEFAULT_PORT = 9515
         | 
| 27 25 | 
             
                    EXECUTABLE = 'chromedriver'
         | 
| 28 26 | 
             
                    SHUTDOWN_SUPPORTED = true
         | 
| @@ -159,24 +159,6 @@ module Selenium | |
| 159 159 | 
             
                      @options[:prefs][name] = value
         | 
| 160 160 | 
             
                    end
         | 
| 161 161 |  | 
| 162 | 
            -
                    #
         | 
| 163 | 
            -
                    # Run Chrome in headless mode.
         | 
| 164 | 
            -
                    # Old headless uses a non-production browser and is set with `--headless`
         | 
| 165 | 
            -
                    # Native headless from v86 - v108 is set with `--headless=chrome`
         | 
| 166 | 
            -
                    # Native headless from v109+ is set with `--headless=new`
         | 
| 167 | 
            -
                    #
         | 
| 168 | 
            -
                    # @example Enable headless mode
         | 
| 169 | 
            -
                    #   options = Selenium::WebDriver::Chrome::Options.new
         | 
| 170 | 
            -
                    #   options.headless!
         | 
| 171 | 
            -
                    #
         | 
| 172 | 
            -
             | 
| 173 | 
            -
                    def headless!
         | 
| 174 | 
            -
                      WebDriver.logger.deprecate('`Options#headless!`',
         | 
| 175 | 
            -
                                                 "`Options#add_argument('--headless=new')`",
         | 
| 176 | 
            -
                                                 id: :headless)
         | 
| 177 | 
            -
                      add_argument '--headless'
         | 
| 178 | 
            -
                    end
         | 
| 179 | 
            -
             | 
| 180 162 | 
             
                    #
         | 
| 181 163 | 
             
                    # Add emulation device information
         | 
| 182 164 | 
             
                    #
         | 
| @@ -26,7 +26,6 @@ module Selenium | |
| 26 26 | 
             
                  autoload :Driver, 'selenium/webdriver/chromium/driver'
         | 
| 27 27 | 
             
                  autoload :Profile, 'selenium/webdriver/chromium/profile'
         | 
| 28 28 | 
             
                  autoload :Options, 'selenium/webdriver/chromium/options'
         | 
| 29 | 
            -
                  autoload :Service, 'selenium/webdriver/chromium/service'
         | 
| 30 29 | 
             
                end # Chromium
         | 
| 31 30 | 
             
              end # WebDriver
         | 
| 32 31 | 
             
            end # Selenium
         | 
| @@ -81,11 +81,11 @@ module Selenium | |
| 81 81 | 
             
                  end
         | 
| 82 82 |  | 
| 83 83 | 
             
                  def exited?
         | 
| 84 | 
            -
                    return unless @pid
         | 
| 84 | 
            +
                    return false unless @pid
         | 
| 85 85 |  | 
| 86 86 | 
             
                    WebDriver.logger.debug("Checking if #{@pid} is exited:", id: :process)
         | 
| 87 87 | 
             
                    _, @status = Process.waitpid2(@pid, Process::WNOHANG | Process::WUNTRACED) if @status.nil?
         | 
| 88 | 
            -
                    return if @status.nil?
         | 
| 88 | 
            +
                    return false if @status.nil?
         | 
| 89 89 |  | 
| 90 90 | 
             
                    exit_code = @status.exitstatus || @status.termsig
         | 
| 91 91 | 
             
                    WebDriver.logger.debug("  -> exit code is #{exit_code.inspect}", id: :process)
         | 
| @@ -23,20 +23,21 @@ module Selenium | |
| 23 23 | 
             
                  def self.path(options, klass)
         | 
| 24 24 | 
             
                    path = klass.driver_path
         | 
| 25 25 | 
             
                    path = path.call if path.is_a?(Proc)
         | 
| 26 | 
            -
                    path ||= Platform.find_binary(klass::EXECUTABLE)
         | 
| 27 26 |  | 
| 28 27 | 
             
                    path ||= begin
         | 
| 29 | 
            -
                      SeleniumManager.driver_path(options)
         | 
| 28 | 
            +
                      SeleniumManager.driver_path(options) unless options.is_a?(Remote::Capabilities)
         | 
| 30 29 | 
             
                    rescue StandardError => e
         | 
| 31 | 
            -
                       | 
| 32 | 
            -
             | 
| 33 | 
            -
             | 
| 30 | 
            +
                      raise Error::NoSuchDriverError, "Unable to obtain #{klass::EXECUTABLE} using Selenium Manager; #{e.message}"
         | 
| 31 | 
            +
                    end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                    begin
         | 
| 34 | 
            +
                      Platform.assert_executable(path)
         | 
| 35 | 
            +
                    rescue TypeError
         | 
| 36 | 
            +
                      raise Error::NoSuchDriverError, "Unable to locate or obtain #{klass::EXECUTABLE}"
         | 
| 37 | 
            +
                    rescue Error::WebDriverError => e
         | 
| 38 | 
            +
                      raise Error::NoSuchDriverError, "#{klass::EXECUTABLE} located, but: #{e.message}"
         | 
| 34 39 | 
             
                    end
         | 
| 35 | 
            -
                    msg = "Unable to locate the #{klass::EXECUTABLE} executable; for more information on how to install drivers, " \
         | 
| 36 | 
            -
                          'see https://www.selenium.dev/documentation/webdriver/getting_started/install_drivers/'
         | 
| 37 | 
            -
                    raise Error::WebDriverError, msg unless path
         | 
| 38 40 |  | 
| 39 | 
            -
                    Platform.assert_executable path
         | 
| 40 41 | 
             
                    path
         | 
| 41 42 | 
             
                  end
         | 
| 42 43 | 
             
                end
         | 
| @@ -34,13 +34,20 @@ module Selenium | |
| 34 34 | 
             
                    WebDriverError
         | 
| 35 35 | 
             
                  end
         | 
| 36 36 |  | 
| 37 | 
            +
                  SUPPORT_MSG = 'For documentation on this error, please visit:'
         | 
| 38 | 
            +
                  ERROR_URL = 'https://www.selenium.dev/documentation/webdriver/troubleshooting/errors'
         | 
| 39 | 
            +
             | 
| 37 40 | 
             
                  class WebDriverError < StandardError; end
         | 
| 38 41 |  | 
| 39 42 | 
             
                  #
         | 
| 40 43 | 
             
                  # An element could not be located on the page using the given search parameters.
         | 
| 41 44 | 
             
                  #
         | 
| 42 45 |  | 
| 43 | 
            -
                  class NoSuchElementError < WebDriverError | 
| 46 | 
            +
                  class NoSuchElementError < WebDriverError
         | 
| 47 | 
            +
                    def initialize(msg = '')
         | 
| 48 | 
            +
                      super("#{msg}; #{SUPPORT_MSG} #{ERROR_URL}#no-such-element-exception")
         | 
| 49 | 
            +
                    end
         | 
| 50 | 
            +
                  end
         | 
| 44 51 |  | 
| 45 52 | 
             
                  #
         | 
| 46 53 | 
             
                  # A command to switch to a frame could not be satisfied because the frame could not be found.
         | 
| @@ -58,7 +65,11 @@ module Selenium | |
| 58 65 | 
             
                  # A command failed because the referenced element is no longer attached to the DOM.
         | 
| 59 66 | 
             
                  #
         | 
| 60 67 |  | 
| 61 | 
            -
                  class StaleElementReferenceError < WebDriverError | 
| 68 | 
            +
                  class StaleElementReferenceError < WebDriverError
         | 
| 69 | 
            +
                    def initialize(msg = '')
         | 
| 70 | 
            +
                      super("#{msg}; #{SUPPORT_MSG} #{ERROR_URL}#stale-element-reference-exception")
         | 
| 71 | 
            +
                    end
         | 
| 72 | 
            +
                  end
         | 
| 62 73 |  | 
| 63 74 | 
             
                  #
         | 
| 64 75 | 
             
                  # A command failed because the referenced shadow root is no longer attached to the DOM.
         | 
| @@ -132,7 +143,11 @@ module Selenium | |
| 132 143 | 
             
                  # Argument was an invalid selector.
         | 
| 133 144 | 
             
                  #
         | 
| 134 145 |  | 
| 135 | 
            -
                  class InvalidSelectorError < WebDriverError | 
| 146 | 
            +
                  class InvalidSelectorError < WebDriverError
         | 
| 147 | 
            +
                    def initialize(msg = '')
         | 
| 148 | 
            +
                      super("#{msg}; #{SUPPORT_MSG} #{ERROR_URL}#invalid-selector-exception")
         | 
| 149 | 
            +
                    end
         | 
| 150 | 
            +
                  end
         | 
| 136 151 |  | 
| 137 152 | 
             
                  #
         | 
| 138 153 | 
             
                  # A new session could not be created.
         | 
| @@ -212,6 +227,16 @@ module Selenium | |
| 212 227 | 
             
                  #
         | 
| 213 228 |  | 
| 214 229 | 
             
                  class UnsupportedOperationError < WebDriverError; end
         | 
| 230 | 
            +
             | 
| 231 | 
            +
                  #
         | 
| 232 | 
            +
                  # Indicates that driver was not specified and could not be located.
         | 
| 233 | 
            +
                  #
         | 
| 234 | 
            +
             | 
| 235 | 
            +
                  class NoSuchDriverError < WebDriverError
         | 
| 236 | 
            +
                    def initialize(msg = '')
         | 
| 237 | 
            +
                      super("#{msg}; #{SUPPORT_MSG} #{ERROR_URL}/driver_location")
         | 
| 238 | 
            +
                    end
         | 
| 239 | 
            +
                  end
         | 
| 215 240 | 
             
                end # Error
         | 
| 216 241 | 
             
              end # WebDriver
         | 
| 217 242 | 
             
            end # Selenium
         | 
| @@ -41,7 +41,7 @@ module Selenium | |
| 41 41 | 
             
                                 :debug?,
         | 
| 42 42 | 
             
                                 :info?,
         | 
| 43 43 | 
             
                                 :warn?,
         | 
| 44 | 
            -
                                 :error | 
| 44 | 
            +
                                 :error?,
         | 
| 45 45 | 
             
                                 :fatal, :fatal?,
         | 
| 46 46 | 
             
                                 :level
         | 
| 47 47 |  | 
| @@ -127,16 +127,20 @@ module Selenium | |
| 127 127 | 
             
                  # @yield see #deprecate
         | 
| 128 128 | 
             
                  #
         | 
| 129 129 | 
             
                  def info(message, id: [], &block)
         | 
| 130 | 
            -
                    unless @first_warning
         | 
| 131 | 
            -
                      @first_warning = true
         | 
| 132 | 
            -
                      info("Details on how to use and modify Selenium logger:\n", id: [:logger_info]) do
         | 
| 133 | 
            -
                        "https://selenium.dev/documentation/webdriver/troubleshooting/logging\n"
         | 
| 134 | 
            -
                      end
         | 
| 135 | 
            -
                    end
         | 
| 136 | 
            -
             | 
| 137 130 | 
             
                    discard_or_log(:info, message, id, &block)
         | 
| 138 131 | 
             
                  end
         | 
| 139 132 |  | 
| 133 | 
            +
                  #
         | 
| 134 | 
            +
                  # Used to supply information that suggests an error occurred
         | 
| 135 | 
            +
                  #
         | 
| 136 | 
            +
                  # @param [String] message
         | 
| 137 | 
            +
                  # @param [Symbol, Array<Sybmol>] id
         | 
| 138 | 
            +
                  # @yield see #deprecate
         | 
| 139 | 
            +
                  #
         | 
| 140 | 
            +
                  def error(message, id: [], &block)
         | 
| 141 | 
            +
                    discard_or_log(:error, message, id, &block)
         | 
| 142 | 
            +
                  end
         | 
| 143 | 
            +
             | 
| 140 144 | 
             
                  #
         | 
| 141 145 | 
             
                  # Used to supply information that suggests action be taken by user
         | 
| 142 146 | 
             
                  #
         | 
| @@ -192,6 +196,15 @@ module Selenium | |
| 192 196 | 
             
                    return if (@ignored & id).any?
         | 
| 193 197 | 
             
                    return if @allowed.any? && (@allowed & id).none?
         | 
| 194 198 |  | 
| 199 | 
            +
                    return if ::Logger::Severity.const_get(level.upcase) < @logger.level
         | 
| 200 | 
            +
             | 
| 201 | 
            +
                    unless @first_warning
         | 
| 202 | 
            +
                      @first_warning = true
         | 
| 203 | 
            +
                      info("Details on how to use and modify Selenium logger:\n", id: [:logger_info]) do
         | 
| 204 | 
            +
                        "https://selenium.dev/documentation/webdriver/troubleshooting/logging\n"
         | 
| 205 | 
            +
                      end
         | 
| 206 | 
            +
                    end
         | 
| 207 | 
            +
             | 
| 195 208 | 
             
                    msg = id.empty? ? message : "[#{id.map(&:inspect).join(', ')}] #{message} "
         | 
| 196 209 | 
             
                    msg += " #{yield}" if block_given?
         | 
| 197 210 |  | 
| @@ -86,12 +86,6 @@ module Selenium | |
| 86 86 |  | 
| 87 87 | 
             
                  def add_option(name, value = nil)
         | 
| 88 88 | 
             
                    name, value = name.first if value.nil? && name.is_a?(Hash)
         | 
| 89 | 
            -
             | 
| 90 | 
            -
                    unless name.to_s.include?(':')
         | 
| 91 | 
            -
                      WebDriver.logger.deprecate('Options#add_option for w3c or browser specific capabilities',
         | 
| 92 | 
            -
                                                 'applicable attribute accessors or pass into constructor',
         | 
| 93 | 
            -
                                                 id: :add_option)
         | 
| 94 | 
            -
                    end
         | 
| 95 89 | 
             
                    @options[name] = value
         | 
| 96 90 | 
             
                  end
         | 
| 97 91 |  | 
| @@ -113,24 +107,11 @@ module Selenium | |
| 113 107 | 
             
                    w3c_options = process_w3c_options(options)
         | 
| 114 108 |  | 
| 115 109 | 
             
                    browser_options = self.class::CAPABILITIES.each_with_object({}) do |(capability_alias, capability_name), hash|
         | 
| 116 | 
            -
                       | 
| 117 | 
            -
                      from_alias = options.delete(capability_alias)
         | 
| 118 | 
            -
                      capability_value = if !from_name.nil? && capability_alias != capability_name
         | 
| 119 | 
            -
                                           WebDriver.logger.deprecate("#{capability_name} as option",
         | 
| 120 | 
            -
                                                                      capability_alias.to_s, id: :option_symbols)
         | 
| 121 | 
            -
                                           from_name
         | 
| 122 | 
            -
                                         elsif !from_alias.nil?
         | 
| 123 | 
            -
                                           from_alias
         | 
| 124 | 
            -
                                         end
         | 
| 125 | 
            -
             | 
| 110 | 
            +
                      capability_value = options.delete(capability_alias)
         | 
| 126 111 | 
             
                      hash[capability_name] = capability_value unless capability_value.nil?
         | 
| 127 112 | 
             
                    end
         | 
| 128 113 |  | 
| 129 | 
            -
                    unless options.empty?
         | 
| 130 | 
            -
                      msg = 'These options are not w3c compliant and will result in failures in a future release'
         | 
| 131 | 
            -
                      WebDriver.logger.warn("#{msg}: #{options}", id: :w3c_options)
         | 
| 132 | 
            -
                      browser_options.merge!(options)
         | 
| 133 | 
            -
                    end
         | 
| 114 | 
            +
                    raise Error::WebDriverError, "These options are not w3c compliant: #{options}" unless options.empty?
         | 
| 134 115 |  | 
| 135 116 | 
             
                    browser_options = {self.class::KEY => browser_options} if defined?(self.class::KEY)
         | 
| 136 117 |  | 
| @@ -145,7 +126,7 @@ module Selenium | |
| 145 126 | 
             
                  end
         | 
| 146 127 |  | 
| 147 128 | 
             
                  def process_w3c_options(options)
         | 
| 148 | 
            -
                    w3c_options = options.select { |key,  | 
| 129 | 
            +
                    w3c_options = options.select { |key, val| w3c?(key) && !val.nil? }
         | 
| 149 130 | 
             
                    w3c_options[:unhandled_prompt_behavior] &&= w3c_options[:unhandled_prompt_behavior]&.to_s&.tr('_', ' ')
         | 
| 150 131 | 
             
                    options.delete_if { |key, _val| w3c?(key) }
         | 
| 151 132 | 
             
                    w3c_options
         | 
| @@ -62,18 +62,6 @@ module Selenium | |
| 62 62 | 
             
                    end
         | 
| 63 63 | 
             
                  end
         | 
| 64 64 |  | 
| 65 | 
            -
                  def bitsize
         | 
| 66 | 
            -
                    @bitsize ||= if defined?(FFI::Platform::ADDRESS_SIZE)
         | 
| 67 | 
            -
                                   FFI::Platform::ADDRESS_SIZE
         | 
| 68 | 
            -
                                 elsif defined?(FFI)
         | 
| 69 | 
            -
                                   FFI.type_size(:pointer) == 4 ? 32 : 64
         | 
| 70 | 
            -
                                 elsif jruby?
         | 
| 71 | 
            -
                                   Integer(ENV_JAVA['sun.arch.data.model'])
         | 
| 72 | 
            -
                                 else
         | 
| 73 | 
            -
                                   1.size == 4 ? 32 : 64
         | 
| 74 | 
            -
                                 end
         | 
| 75 | 
            -
                  end
         | 
| 76 | 
            -
             | 
| 77 65 | 
             
                  def jruby?
         | 
| 78 66 | 
             
                    engine == :jruby
         | 
| 79 67 | 
             
                  end
         | 
| @@ -158,43 +146,6 @@ module Selenium | |
| 158 146 | 
             
                    at_exit { yield if Process.pid == pid }
         | 
| 159 147 | 
             
                  end
         | 
| 160 148 |  | 
| 161 | 
            -
                  def find_binary(*binary_names)
         | 
| 162 | 
            -
                    paths = ENV['PATH'].split(File::PATH_SEPARATOR)
         | 
| 163 | 
            -
             | 
| 164 | 
            -
                    if windows?
         | 
| 165 | 
            -
                      binary_names.map! { |n| "#{n}.exe" }
         | 
| 166 | 
            -
                      binary_names.dup.each { |n| binary_names << n.gsub('exe', 'bat') }
         | 
| 167 | 
            -
                    end
         | 
| 168 | 
            -
             | 
| 169 | 
            -
                    binary_names.each do |binary_name|
         | 
| 170 | 
            -
                      paths.each do |path|
         | 
| 171 | 
            -
                        full_path = File.join(path, binary_name)
         | 
| 172 | 
            -
                        full_path = unix_path(full_path) if windows?
         | 
| 173 | 
            -
                        exe = Dir.glob(full_path).find { |f| File.executable?(f) }
         | 
| 174 | 
            -
                        return exe if exe
         | 
| 175 | 
            -
                      end
         | 
| 176 | 
            -
                    end
         | 
| 177 | 
            -
             | 
| 178 | 
            -
                    nil
         | 
| 179 | 
            -
                  end
         | 
| 180 | 
            -
             | 
| 181 | 
            -
                  def find_in_program_files(*binary_names)
         | 
| 182 | 
            -
                    paths = [
         | 
| 183 | 
            -
                      ENV.fetch('PROGRAMFILES', '\\Program Files'),
         | 
| 184 | 
            -
                      ENV.fetch('ProgramFiles(x86)', '\\Program Files (x86)'),
         | 
| 185 | 
            -
                      ENV.fetch('ProgramW6432', '\\Program Files')
         | 
| 186 | 
            -
                    ]
         | 
| 187 | 
            -
             | 
| 188 | 
            -
                    paths.each do |root|
         | 
| 189 | 
            -
                      binary_names.each do |name|
         | 
| 190 | 
            -
                        exe = File.join(root, name)
         | 
| 191 | 
            -
                        return exe if File.executable?(exe)
         | 
| 192 | 
            -
                      end
         | 
| 193 | 
            -
                    end
         | 
| 194 | 
            -
             | 
| 195 | 
            -
                    nil
         | 
| 196 | 
            -
                  end
         | 
| 197 | 
            -
             | 
| 198 149 | 
             
                  def localhost
         | 
| 199 150 | 
             
                    info = Socket.getaddrinfo 'localhost', 80, Socket::AF_INET, Socket::SOCK_STREAM
         | 
| 200 151 |  | 
| @@ -27,20 +27,36 @@ module Selenium | |
| 27 27 | 
             
                # @api private
         | 
| 28 28 | 
             
                #
         | 
| 29 29 | 
             
                class SeleniumManager
         | 
| 30 | 
            -
                  BIN_PATH = '../../../../../bin'
         | 
| 31 | 
            -
             | 
| 32 30 | 
             
                  class << self
         | 
| 31 | 
            +
                    attr_writer :bin_path
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                    def bin_path
         | 
| 34 | 
            +
                      @bin_path ||= '../../../../../bin'
         | 
| 35 | 
            +
                    end
         | 
| 36 | 
            +
             | 
| 33 37 | 
             
                    # @param [Options] options browser options.
         | 
| 34 38 | 
             
                    # @return [String] the path to the correct driver.
         | 
| 35 39 | 
             
                    def driver_path(options)
         | 
| 36 | 
            -
                       | 
| 37 | 
            -
             | 
| 40 | 
            +
                      command = generate_command(binary, options)
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                      output = run(*command)
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                      browser_path = output['browser_path']
         | 
| 45 | 
            +
                      driver_path = output['driver_path']
         | 
| 46 | 
            +
                      Platform.assert_executable driver_path
         | 
| 38 47 |  | 
| 39 | 
            -
                       | 
| 40 | 
            -
                         | 
| 48 | 
            +
                      if options.respond_to? :binary
         | 
| 49 | 
            +
                        options.binary = browser_path
         | 
| 50 | 
            +
                        options.browser_version = nil
         | 
| 41 51 | 
             
                      end
         | 
| 42 52 |  | 
| 43 | 
            -
                       | 
| 53 | 
            +
                      driver_path
         | 
| 54 | 
            +
                    end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                    private
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                    def generate_command(binary, options)
         | 
| 59 | 
            +
                      command = [binary, '--browser', options.browser_name]
         | 
| 44 60 | 
             
                      if options.browser_version
         | 
| 45 61 | 
             
                        command << '--browser-version'
         | 
| 46 62 | 
             
                        command << options.browser_version
         | 
| @@ -49,21 +65,17 @@ module Selenium | |
| 49 65 | 
             
                        command << '--browser-path'
         | 
| 50 66 | 
             
                        command << options.binary.gsub('\\', '\\\\\\')
         | 
| 51 67 | 
             
                      end
         | 
| 52 | 
            -
                       | 
| 53 | 
            -
             | 
| 54 | 
            -
             | 
| 55 | 
            -
                       | 
| 56 | 
            -
                       | 
| 57 | 
            -
             | 
| 58 | 
            -
                      location
         | 
| 68 | 
            +
                      if options.proxy
         | 
| 69 | 
            +
                        command << '--proxy'
         | 
| 70 | 
            +
                        (command << options.proxy.ssl) || options.proxy.http
         | 
| 71 | 
            +
                      end
         | 
| 72 | 
            +
                      command
         | 
| 59 73 | 
             
                    end
         | 
| 60 74 |  | 
| 61 | 
            -
                    private
         | 
| 62 | 
            -
             | 
| 63 75 | 
             
                    # @return [String] the path to the correct selenium manager
         | 
| 64 76 | 
             
                    def binary
         | 
| 65 77 | 
             
                      @binary ||= begin
         | 
| 66 | 
            -
                        path = File.expand_path( | 
| 78 | 
            +
                        path = File.expand_path(bin_path, __FILE__)
         | 
| 67 79 | 
             
                        path << if Platform.windows?
         | 
| 68 80 | 
             
                                  '/windows/selenium-manager.exe'
         | 
| 69 81 | 
             
                                elsif Platform.mac?
         | 
| @@ -72,32 +84,43 @@ module Selenium | |
| 72 84 | 
             
                                  '/linux/selenium-manager'
         | 
| 73 85 | 
             
                                end
         | 
| 74 86 | 
             
                        location = File.expand_path(path, __FILE__)
         | 
| 75 | 
            -
             | 
| 76 | 
            -
             | 
| 87 | 
            +
             | 
| 88 | 
            +
                        begin
         | 
| 89 | 
            +
                          Platform.assert_file(location)
         | 
| 90 | 
            +
                          Platform.assert_executable(location)
         | 
| 91 | 
            +
                        rescue TypeError
         | 
| 92 | 
            +
                          raise Error::WebDriverError,
         | 
| 93 | 
            +
                                "Unable to locate or obtain Selenium Manager binary; #{location} is not a valid file object"
         | 
| 94 | 
            +
                        rescue Error::WebDriverError => e
         | 
| 95 | 
            +
                          raise Error::WebDriverError, "Selenium Manager binary located, but #{e.message}"
         | 
| 77 96 | 
             
                        end
         | 
| 78 97 |  | 
| 79 | 
            -
                        WebDriver.logger.debug("Selenium Manager found at #{location}", id: :selenium_manager)
         | 
| 98 | 
            +
                        WebDriver.logger.debug("Selenium Manager binary found at #{location}", id: :selenium_manager)
         | 
| 80 99 | 
             
                        location
         | 
| 81 100 | 
             
                      end
         | 
| 82 101 | 
             
                    end
         | 
| 83 102 |  | 
| 84 103 | 
             
                    def run(*command)
         | 
| 104 | 
            +
                      command += %w[--output json]
         | 
| 105 | 
            +
                      command << '--debug' if WebDriver.logger.debug?
         | 
| 106 | 
            +
             | 
| 85 107 | 
             
                      WebDriver.logger.debug("Executing Process #{command}", id: :selenium_manager)
         | 
| 86 108 |  | 
| 87 109 | 
             
                      begin
         | 
| 88 110 | 
             
                        stdout, stderr, status = Open3.capture3(*command)
         | 
| 89 111 | 
             
                        json_output = stdout.empty? ? nil : JSON.parse(stdout)
         | 
| 90 | 
            -
                        result = json_output | 
| 112 | 
            +
                        result = json_output['result']
         | 
| 91 113 | 
             
                      rescue StandardError => e
         | 
| 92 | 
            -
                        raise Error::WebDriverError, "Unsuccessful command executed: #{command} | 
| 114 | 
            +
                        raise Error::WebDriverError, "Unsuccessful command executed: #{command}; #{e.message}"
         | 
| 93 115 | 
             
                      end
         | 
| 94 116 |  | 
| 95 | 
            -
                       | 
| 96 | 
            -
                         | 
| 117 | 
            +
                      (json_output&.fetch('logs') || []).each do |log|
         | 
| 118 | 
            +
                        level = log['level'].casecmp('info').zero? ? 'debug' : log['level'].downcase
         | 
| 119 | 
            +
                        WebDriver.logger.send(level, log['message'], id: :selenium_manager)
         | 
| 97 120 | 
             
                      end
         | 
| 98 121 |  | 
| 99 | 
            -
                       | 
| 100 | 
            -
                         | 
| 122 | 
            +
                      if status.exitstatus.positive?
         | 
| 123 | 
            +
                        raise Error::WebDriverError, "Unsuccessful command executed: #{command}\n#{result}#{stderr}"
         | 
| 101 124 | 
             
                      end
         | 
| 102 125 |  | 
| 103 126 | 
             
                      result
         | 
| @@ -81,8 +81,7 @@ module Selenium | |
| 81 81 | 
             
                           else
         | 
| 82 82 | 
             
                             log
         | 
| 83 83 | 
             
                           end
         | 
| 84 | 
            -
             | 
| 85 | 
            -
                    @args = args.is_a?(Hash) ? extract_service_args(args) : args
         | 
| 84 | 
            +
                    @args = args
         | 
| 86 85 |  | 
| 87 86 | 
             
                    raise Error::WebDriverError, "invalid port: #{@port}" if @port < 1
         | 
| 88 87 | 
             
                  end
         | 
| @@ -94,15 +93,6 @@ module Selenium | |
| 94 93 | 
             
                  def shutdown_supported
         | 
| 95 94 | 
             
                    self.class::SHUTDOWN_SUPPORTED
         | 
| 96 95 | 
             
                  end
         | 
| 97 | 
            -
             | 
| 98 | 
            -
                  protected
         | 
| 99 | 
            -
             | 
| 100 | 
            -
                  def extract_service_args(driver_opts)
         | 
| 101 | 
            -
                    WebDriver.logger.deprecate('initializing Service class with :args using Hash',
         | 
| 102 | 
            -
                                               ':args parameter with an Array of String values',
         | 
| 103 | 
            -
                                               id: :driver_opts)
         | 
| 104 | 
            -
                    driver_opts.key?(:args) ? driver_opts.delete(:args) : []
         | 
| 105 | 
            -
                  end
         | 
| 106 96 | 
             
                end # Service
         | 
| 107 97 | 
             
              end # WebDriver
         | 
| 108 98 | 
             
            end # Selenium
         | 
| @@ -26,6 +26,20 @@ module Selenium | |
| 26 26 | 
             
                    KEY = 'ms:edgeOptions'
         | 
| 27 27 | 
             
                    BROWSER = 'MicrosoftEdge'
         | 
| 28 28 |  | 
| 29 | 
            +
                    #
         | 
| 30 | 
            +
                    # Changes the browser name enable webview2
         | 
| 31 | 
            +
                    # see: https://learn.microsoft.com/en-us/microsoft-edge/webview2/how-to/webdriver
         | 
| 32 | 
            +
                    # Automation of WebView2 apps with Microsoft Edge WebDriver
         | 
| 33 | 
            +
                    #
         | 
| 34 | 
            +
                    # @example Enable webview2
         | 
| 35 | 
            +
                    #   options = Selenium::WebDriver::Edge::Options.new
         | 
| 36 | 
            +
                    #   options.webview2!
         | 
| 37 | 
            +
                    #
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                    def webview2!
         | 
| 40 | 
            +
                      @options[:browser_name] = 'webview2'
         | 
| 41 | 
            +
                    end
         | 
| 42 | 
            +
             | 
| 29 43 | 
             
                    private
         | 
| 30 44 |  | 
| 31 45 | 
             
                    def enable_logging(browser_options)
         | 
| @@ -17,12 +17,10 @@ | |
| 17 17 | 
             
            # specific language governing permissions and limitations
         | 
| 18 18 | 
             
            # under the License.
         | 
| 19 19 |  | 
| 20 | 
            -
            require 'selenium/webdriver/chromium/service'
         | 
| 21 | 
            -
             | 
| 22 20 | 
             
            module Selenium
         | 
| 23 21 | 
             
              module WebDriver
         | 
| 24 22 | 
             
                module Edge
         | 
| 25 | 
            -
                  class Service <  | 
| 23 | 
            +
                  class Service < WebDriver::Service
         | 
| 26 24 | 
             
                    DEFAULT_PORT = 9515
         | 
| 27 25 | 
             
                    EXECUTABLE = 'msedgedriver'
         | 
| 28 26 | 
             
                    SHUTDOWN_SUPPORTED = true
         | 
| @@ -99,21 +99,6 @@ module Selenium | |
| 99 99 | 
             
                      @options[:prefs][name] = value
         | 
| 100 100 | 
             
                    end
         | 
| 101 101 |  | 
| 102 | 
            -
                    #
         | 
| 103 | 
            -
                    # Run Firefox in headless mode.
         | 
| 104 | 
            -
                    #
         | 
| 105 | 
            -
                    # @example Enable headless mode
         | 
| 106 | 
            -
                    #   options = Selenium::WebDriver::Firefox::Options.new
         | 
| 107 | 
            -
                    #   options.headless!
         | 
| 108 | 
            -
                    #
         | 
| 109 | 
            -
             | 
| 110 | 
            -
                    def headless!
         | 
| 111 | 
            -
                      WebDriver.logger.deprecate('`Options#headless!`',
         | 
| 112 | 
            -
                                                 "`Options#add_argument('-headless')`",
         | 
| 113 | 
            -
                                                 id: :headless)
         | 
| 114 | 
            -
                      add_argument '-headless'
         | 
| 115 | 
            -
                    end
         | 
| 116 | 
            -
             | 
| 117 102 | 
             
                    #
         | 
| 118 103 | 
             
                    # Sets Firefox profile.
         | 
| 119 104 | 
             
                    #
         | 
| @@ -24,18 +24,6 @@ module Selenium | |
| 24 24 | 
             
                    DEFAULT_PORT = 4444
         | 
| 25 25 | 
             
                    EXECUTABLE = 'geckodriver'
         | 
| 26 26 | 
             
                    SHUTDOWN_SUPPORTED = false
         | 
| 27 | 
            -
             | 
| 28 | 
            -
                    private
         | 
| 29 | 
            -
             | 
| 30 | 
            -
                    def extract_service_args(driver_opts)
         | 
| 31 | 
            -
                      driver_args = super
         | 
| 32 | 
            -
                      driver_opts = driver_opts.dup
         | 
| 33 | 
            -
                      driver_args << "--binary=#{driver_opts[:binary]}" if driver_opts.key?(:binary)
         | 
| 34 | 
            -
                      driver_args << "--log=#{driver_opts[:log]}" if driver_opts.key?(:log)
         | 
| 35 | 
            -
                      driver_args << "--marionette-port=#{driver_opts[:marionette_port]}" if driver_opts.key?(:marionette_port)
         | 
| 36 | 
            -
                      driver_args << "--host=#{driver_opts[:host]}" if driver_opts.key?(:host)
         | 
| 37 | 
            -
                      driver_args
         | 
| 38 | 
            -
                    end
         | 
| 39 27 | 
             
                  end # Service
         | 
| 40 28 | 
             
                end # Firefox
         | 
| 41 29 | 
             
              end # WebDriver
         | 
| @@ -41,7 +41,8 @@ module Selenium | |
| 41 41 | 
             
                      use_per_process_proxy: 'ie.usePerProcessProxy',
         | 
| 42 42 | 
             
                      use_legacy_file_upload_dialog_handling: 'ie.useLegacyFileUploadDialogHandling',
         | 
| 43 43 | 
             
                      attach_to_edge_chrome: 'ie.edgechromium',
         | 
| 44 | 
            -
                      edge_executable_path: 'ie.edgepath'
         | 
| 44 | 
            +
                      edge_executable_path: 'ie.edgepath',
         | 
| 45 | 
            +
                      ignore_process_match: 'ie.ignoreprocessmatch'
         | 
| 45 46 | 
             
                    }.freeze
         | 
| 46 47 | 
             
                    BROWSER = 'internet explorer'
         | 
| 47 48 |  | 
| @@ -24,22 +24,6 @@ module Selenium | |
| 24 24 | 
             
                    DEFAULT_PORT = 5555
         | 
| 25 25 | 
             
                    EXECUTABLE = 'IEDriverServer'
         | 
| 26 26 | 
             
                    SHUTDOWN_SUPPORTED = true
         | 
| 27 | 
            -
             | 
| 28 | 
            -
                    private
         | 
| 29 | 
            -
             | 
| 30 | 
            -
                    def extract_service_args(driver_opts)
         | 
| 31 | 
            -
                      driver_args = super
         | 
| 32 | 
            -
                      driver_opts = driver_opts.dup
         | 
| 33 | 
            -
                      driver_args << "--log-level=#{driver_opts[:log_level].to_s.upcase}" if driver_opts.key?(:log_level)
         | 
| 34 | 
            -
                      driver_args << "--log-file=#{driver_opts[:log_file]}" if driver_opts.key?(:log_file)
         | 
| 35 | 
            -
                      if driver_opts.key?(:implementation)
         | 
| 36 | 
            -
                        driver_args << "--implementation=#{driver_opts[:implementation].to_s.upcase}"
         | 
| 37 | 
            -
                      end
         | 
| 38 | 
            -
                      driver_args << "--host=#{driver_opts[:host]}" if driver_opts.key?(:host)
         | 
| 39 | 
            -
                      driver_args << "--extract_path=#{driver_opts[:extract_path]}" if driver_opts.key?(:extract_path)
         | 
| 40 | 
            -
                      driver_args << '--silent' if driver_opts[:silent] == true
         | 
| 41 | 
            -
                      driver_args
         | 
| 42 | 
            -
                    end
         | 
| 43 27 | 
             
                  end # Server
         | 
| 44 28 | 
             
                end # IE
         | 
| 45 29 | 
             
              end # WebDriver
         | 
| @@ -53,83 +53,11 @@ module Selenium | |
| 53 53 | 
             
                      end
         | 
| 54 54 | 
             
                    end
         | 
| 55 55 |  | 
| 56 | 
            -
                    #
         | 
| 57 | 
            -
                    # Backward compatibility
         | 
| 58 | 
            -
                    #
         | 
| 59 | 
            -
             | 
| 60 | 
            -
                    def version
         | 
| 61 | 
            -
                      WebDriver.logger.deprecate('`Capabilities#version`', '`Capabilities#browser_version`', id: :jwp_caps)
         | 
| 62 | 
            -
                      browser_version
         | 
| 63 | 
            -
                    end
         | 
| 64 | 
            -
             | 
| 65 | 
            -
                    def version=(value)
         | 
| 66 | 
            -
                      WebDriver.logger.deprecate('`Capabilities#version=`', '`Capabilities#browser_version=`', id: :jwp_caps)
         | 
| 67 | 
            -
                      self.browser_version = value
         | 
| 68 | 
            -
                    end
         | 
| 69 | 
            -
             | 
| 70 | 
            -
                    def platform
         | 
| 71 | 
            -
                      WebDriver.logger.deprecate('`Capabilities#platform`', '`Capabilities#platform_name`', id: :jwp_caps)
         | 
| 72 | 
            -
                      platform_name
         | 
| 73 | 
            -
                    end
         | 
| 74 | 
            -
             | 
| 75 | 
            -
                    def platform=(value)
         | 
| 76 | 
            -
                      WebDriver.logger.deprecate('`Capabilities#platform=`', '`Capabilities#platform_name=`', id: :jwp_caps)
         | 
| 77 | 
            -
                      self.platform_name = value
         | 
| 78 | 
            -
                    end
         | 
| 79 | 
            -
             | 
| 80 56 | 
             
                    #
         | 
| 81 57 | 
             
                    # Convenience methods for the common choices.
         | 
| 82 58 | 
             
                    #
         | 
| 83 59 |  | 
| 84 60 | 
             
                    class << self
         | 
| 85 | 
            -
                      def chrome(opts = {})
         | 
| 86 | 
            -
                        WebDriver.logger.deprecate('Remote::Capabilities.chrome', 'Options.chrome', id: :caps_browsers)
         | 
| 87 | 
            -
                        new({
         | 
| 88 | 
            -
                          browser_name: 'chrome'
         | 
| 89 | 
            -
                        }.merge(opts))
         | 
| 90 | 
            -
                      end
         | 
| 91 | 
            -
             | 
| 92 | 
            -
                      def edge(opts = {})
         | 
| 93 | 
            -
                        WebDriver.logger.deprecate('Remote::Capabilities.edge', 'Options.edge', id: :caps_browsers)
         | 
| 94 | 
            -
                        new({
         | 
| 95 | 
            -
                          browser_name: 'MicrosoftEdge'
         | 
| 96 | 
            -
                        }.merge(opts))
         | 
| 97 | 
            -
                      end
         | 
| 98 | 
            -
                      alias microsoftedge edge
         | 
| 99 | 
            -
             | 
| 100 | 
            -
                      def firefox(opts = {})
         | 
| 101 | 
            -
                        WebDriver.logger.deprecate('Remote::Capabilities.firefox', 'Options.firefox', id: :caps_browsers)
         | 
| 102 | 
            -
                        new({
         | 
| 103 | 
            -
                          browser_name: 'firefox'
         | 
| 104 | 
            -
                        }.merge(opts))
         | 
| 105 | 
            -
                      end
         | 
| 106 | 
            -
                      alias ff firefox
         | 
| 107 | 
            -
             | 
| 108 | 
            -
                      def safari(opts = {})
         | 
| 109 | 
            -
                        WebDriver.logger.deprecate('Remote::Capabilities.safari', 'Options.safari', id: :caps_browsers)
         | 
| 110 | 
            -
                        new({
         | 
| 111 | 
            -
                          browser_name: Selenium::WebDriver::Safari.technology_preview? ? 'Safari Technology Preview' : 'safari'
         | 
| 112 | 
            -
                        }.merge(opts))
         | 
| 113 | 
            -
                      end
         | 
| 114 | 
            -
             | 
| 115 | 
            -
                      def htmlunit(opts = {})
         | 
| 116 | 
            -
                        WebDriver.logger.deprecate('Remote::Capabilities.htmlunit',
         | 
| 117 | 
            -
                                                   'as argument in constructor',
         | 
| 118 | 
            -
                                                   id: :caps_browsers)
         | 
| 119 | 
            -
                        new({
         | 
| 120 | 
            -
                          browser_name: 'htmlunit'
         | 
| 121 | 
            -
                        }.merge(opts))
         | 
| 122 | 
            -
                      end
         | 
| 123 | 
            -
             | 
| 124 | 
            -
                      def internet_explorer(opts = {})
         | 
| 125 | 
            -
                        WebDriver.logger.deprecate('Remote::Capabilities.ie', 'Options.ie', id: :caps_browsers)
         | 
| 126 | 
            -
                        new({
         | 
| 127 | 
            -
                          browser_name: 'internet explorer',
         | 
| 128 | 
            -
                          platform_name: :windows
         | 
| 129 | 
            -
                        }.merge(opts))
         | 
| 130 | 
            -
                      end
         | 
| 131 | 
            -
                      alias ie internet_explorer
         | 
| 132 | 
            -
             | 
| 133 61 | 
             
                      def always_match(capabilities)
         | 
| 134 62 | 
             
                        new(always_match: capabilities)
         | 
| 135 63 | 
             
                      end
         | 
| @@ -16,8 +16,6 @@ | |
| 16 16 | 
             
            # KIND, either express or implied.  See the License for the
         | 
| 17 17 | 
             
            # specific language governing permissions and limitations
         | 
| 18 18 | 
             
            # under the License.
         | 
| 19 | 
            -
             | 
| 20 | 
            -
            require 'net/https'
         | 
| 21 19 | 
             
            require 'ipaddr'
         | 
| 22 20 |  | 
| 23 21 | 
             
            module Selenium
         | 
| @@ -96,6 +94,7 @@ module Selenium | |
| 96 94 | 
             
                        end
         | 
| 97 95 |  | 
| 98 96 | 
             
                        if response.is_a? Net::HTTPRedirection
         | 
| 97 | 
            +
                          WebDriver.logger.debug("Redirect to #{response['Location']}; times: #{redirects}")
         | 
| 99 98 | 
             
                          raise Error::WebDriverError, 'too many redirects' if redirects >= MAX_REDIRECTS
         | 
| 100 99 |  | 
| 101 100 | 
             
                          request(:get, URI.parse(response['Location']), DEFAULT_HEADERS.dup, nil, redirects + 1)
         | 
| @@ -24,6 +24,16 @@ module Selenium | |
| 24 24 | 
             
                    DEFAULT_PORT = 7050
         | 
| 25 25 | 
             
                    EXECUTABLE = 'safaridriver'
         | 
| 26 26 | 
             
                    SHUTDOWN_SUPPORTED = false
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                    def initialize(path: nil, port: nil, log: nil, args: nil)
         | 
| 29 | 
            +
                      raise Error::WebDriverError, 'Safari Service does not support setting log output' if log
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                      super
         | 
| 32 | 
            +
                    end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                    def log=(*)
         | 
| 35 | 
            +
                      raise Error::WebDriverError, 'Safari Service does not support setting log output'
         | 
| 36 | 
            +
                    end
         | 
| 27 37 | 
             
                  end # Service
         | 
| 28 38 | 
             
                end # Safari
         | 
| 29 39 | 
             
              end # WebDriver
         | 
    
        data/selenium-webdriver.gemspec
    CHANGED
    
    | @@ -54,6 +54,7 @@ Gem::Specification.new do |s| | |
| 54 54 | 
             
              s.add_runtime_dependency 'websocket', ['~> 1.0']
         | 
| 55 55 |  | 
| 56 56 | 
             
              s.add_development_dependency 'rack', ['~> 2.0']
         | 
| 57 | 
            +
              s.add_development_dependency 'rake', ['~> 13.0']
         | 
| 57 58 | 
             
              s.add_development_dependency 'rspec', ['~> 3.0']
         | 
| 58 59 | 
             
              s.add_development_dependency 'rubocop', ['~> 1.42']
         | 
| 59 60 | 
             
              s.add_development_dependency 'rubocop-performance', ['~> 1.15']
         | 
    
        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.11.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-07-31 00:00:00.000000000 Z
         | 
| 14 14 | 
             
            dependencies:
         | 
| 15 15 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 16 16 | 
             
              name: rexml
         | 
| @@ -80,6 +80,20 @@ dependencies: | |
| 80 80 | 
             
                - - "~>"
         | 
| 81 81 | 
             
                  - !ruby/object:Gem::Version
         | 
| 82 82 | 
             
                    version: '2.0'
         | 
| 83 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 84 | 
            +
              name: rake
         | 
| 85 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 86 | 
            +
                requirements:
         | 
| 87 | 
            +
                - - "~>"
         | 
| 88 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 89 | 
            +
                    version: '13.0'
         | 
| 90 | 
            +
              type: :development
         | 
| 91 | 
            +
              prerelease: false
         | 
| 92 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 93 | 
            +
                requirements:
         | 
| 94 | 
            +
                - - "~>"
         | 
| 95 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 96 | 
            +
                    version: '13.0'
         | 
| 83 97 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 84 98 | 
             
              name: rspec
         | 
| 85 99 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -228,7 +242,6 @@ files: | |
| 228 242 | 
             
            - lib/selenium/webdriver/chromium/features.rb
         | 
| 229 243 | 
             
            - lib/selenium/webdriver/chromium/options.rb
         | 
| 230 244 | 
             
            - lib/selenium/webdriver/chromium/profile.rb
         | 
| 231 | 
            -
            - lib/selenium/webdriver/chromium/service.rb
         | 
| 232 245 | 
             
            - lib/selenium/webdriver/common.rb
         | 
| 233 246 | 
             
            - lib/selenium/webdriver/common/action_builder.rb
         | 
| 234 247 | 
             
            - lib/selenium/webdriver/common/alert.rb
         | 
| @@ -1,42 +0,0 @@ | |
| 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 Chromium
         | 
| 23 | 
            -
                  class Service < WebDriver::Service
         | 
| 24 | 
            -
                    protected
         | 
| 25 | 
            -
             | 
| 26 | 
            -
                    def extract_service_args(driver_opts)
         | 
| 27 | 
            -
                      driver_args = super
         | 
| 28 | 
            -
                      driver_opts = driver_opts.dup
         | 
| 29 | 
            -
                      driver_args << "--log-path=#{driver_opts.delete(:log_path)}" if driver_opts.key?(:log_path)
         | 
| 30 | 
            -
                      driver_args << "--url-base=#{driver_opts.delete(:url_base)}" if driver_opts.key?(:url_base)
         | 
| 31 | 
            -
                      driver_args << "--port-server=#{driver_opts.delete(:port_server)}" if driver_opts.key?(:port_server)
         | 
| 32 | 
            -
                      if driver_opts.key?(:whitelisted_ips)
         | 
| 33 | 
            -
                        driver_args << "--whitelisted-ips=#{driver_opts.delete(:whitelisted_ips)}"
         | 
| 34 | 
            -
                      end
         | 
| 35 | 
            -
                      driver_args << '--verbose' if driver_opts.key?(:verbose)
         | 
| 36 | 
            -
                      driver_args << '--silent' if driver_opts.key?(:silent)
         | 
| 37 | 
            -
                      driver_args
         | 
| 38 | 
            -
                    end
         | 
| 39 | 
            -
                  end # Service
         | 
| 40 | 
            -
                end # Chromium
         | 
| 41 | 
            -
              end # WebDriver
         | 
| 42 | 
            -
            end # Selenium
         |