这是本节的多页打印视图。
点击此处打印 .
返回本页常规视图 .
双向协议 Selenium正在与浏览器供应商合作创建
WebDriver双向协议  ,
作为一种提供稳定的跨浏览器API的方法,
该API使用双向协议处理
各种浏览器的通用自动化以及特定测试的需求.
在此之前, 寻求此功能的用户
必须忍受当前实现的全部问题和局限.
严格限制请求响应命令的传统WebDriver模型,
将从user agent转变为基于WebSockets的软件控制,
通过这样完善流事件的能力,
以便更好地匹配浏览器DOM的事件性质.
While the specification is in works, the browser vendors are parallely implementing
the WebDriver BiDirectional Protocol .
Refer web-platform-tests dashboard 
to see how far along the browser vendors are.
Selenium is trying to keep up with the browser vendors and has started implementing W3C BiDi APIs.
The goal is to ensure APIs are W3C compliant and uniform among the different language bindings.
However, until the specification and corresponding Selenium implementation is complete there are many useful things that
CDP offers. Selenium offers some useful helper classes that use CDP.
1 - Chrome DevTools Many browsers provide “DevTools” – a set of tools that are integrated with the browser that
developers can use to debug web apps and explore the performance of their pages. Google Chrome’s
DevTools make use of a protocol called the Chrome DevTools Protocol (or “CDP” for short).
As the name suggests, this is not designed for testing, nor to have a stable API, so functionality
is highly dependent on the version of the browser.
The WebDriver BiDirectional Protocol  is the next generation of the
W3C WebDriver protocol and aims to provide a stable API implemented by all browsers, but it’s not yet complete.
Until it is, Selenium provides access to
the CDP for those browsers that implement it (such as Google Chrome, or Microsoft Edge, and
Firefox), allowing you to enhance your tests in interesting ways. Some examples of what you can
do with it are given below.
There are three different ways to access Chrome DevTools in Selenium. If you look for other examples online,
you will likely see each of these mixed and matched.
The CDP Endpoint  was the first option available to users.
It only works for the most simple things (setting state, getting basic information), and you
have to know the “magic strings” for the domain and methods and key value pairs.
For basic requirements, this might be simpler than the other options. These methods are only temporarily supported. The CDP API  is an improvement on just using the endpoint because you can set
do things asynchronously. Instead of a String and a Map, you can access the supported classes,
methods and parameters in the code. These methods are also only temporarily supported. The BiDi API  option should be used whenever possible because it
abstracts away the implementation details entirely and will work with either CDP or WebDriver-BiDi
when Selenium moves away from CDP. Examples With Limited Value There are a number of commonly cited examples for using CDP that are of limited practical value.
Geo Location  — almost all sites use the IP address to determine physical location,
so setting an emulated geolocation rarely has the desired effect.Overriding Device Metrics  — Chrome provides a great API for setting Mobile Emulation 
in the Options classes, which is generally superior to attempting to do this with CDP.Check out the examples in these documents for ways to do additional useful things:
1.1 - Chrome DevTools Protocol Endpoint Google provides a /cdp/execute endpoint that can be accessed directly. Each Selenium binding provides a method that allows you to pass the CDP domain as a String, and the required parameters as a simple Map.
These methods will eventually be removed. It is recommended to use the WebDriver-BiDi  or WebDriver Bidi APIs 
methods where possible to ensure future compatibility.
Usage Generally you should prefer the use of the CDP API  over this approach,
but sometimes the syntax is cleaner or significantly more simple.
Limitations include:
It only works for use cases that are limited to setting or getting information;
any actual asynchronous interactions require another implementation You have to know the exactly correct “magic strings” for domains and keys It is possible that an update to Chrome will change the required parameters Examples Set Cookie An alternate implementation can be found at CDP API Set Cookie 
Java 
Python 
CSharp 
Ruby 
JavaScript 
Kotlin      Map < String ,   Object >   cookie   =   new   HashMap <> (); 
      cookie . put ( "name" ,   "cheese" ); 
      cookie . put ( "value" ,   "gouda" ); 
      cookie . put ( "domain" ,   "www.selenium.dev" ); 
      cookie . put ( "secure" ,   true ); 
 
      (( HasCdp )   driver ). executeCdpCommand ( "Network.setCookie" ,   cookie );     cookie  =  { 'name' :  'cheese' , 
               'value' :  'gouda' , 
               'domain' :  'www.selenium.dev' , 
               'secure' :  True } 
 
     driver . execute_cdp_cmd ( 'Network.setCookie' ,  cookie )              var  cookie  =  new  Dictionary < string ,  object > 
             { 
                 {  "name" ,  "cheese"  }, 
                 {  "value" ,  "gouda"  }, 
                 {  "domain" ,  "www.selenium.dev"  }, 
                 {  "secure" ,  true  } 
             }; 
 
             (( ChromeDriver ) driver ). ExecuteCdpCommand ( "Network.setCookie" ,  cookie );  The CDP API Set Cookie  implementation should be preferred
    cookie  =  { name :  'cheese' , 
               value :  'gouda' , 
               domain :  'www.selenium.dev' , 
               secure :  true } 
 
     driver . execute_cdp ( 'Network.setCookie' ,  ** cookie )  An alternate implementation can be found at CDP API Performance Metrics 
Java 
Python 
CSharp 
Ruby 
JavaScript 
Kotlin The CDP API Performance Metrics  implementation should be preferred
     (( HasCdp )   driver ). executeCdpCommand ( "Performance.enable" ,   new   HashMap <> ()); 
 
      Map < String ,   Object >   response   = 
          (( HasCdp )   driver ). executeCdpCommand ( "Performance.getMetrics" ,   new   HashMap <> ());     driver . execute_cdp_cmd ( 'Performance.enable' ,  {}) 
 
     metric_list  =  driver . execute_cdp_cmd ( 'Performance.getMetrics' ,  {})[ "metrics" ]              (( ChromeDriver ) driver ). ExecuteCdpCommand ( "Performance.enable" ,  emptyDictionary ); 
 
             Dictionary < string ,  object >  response  =  ( Dictionary < string ,  object >)(( ChromeDriver ) driver ) 
                 . ExecuteCdpCommand ( "Performance.getMetrics" ,  emptyDictionary );  The CDP API Performance Metrics  implementation should be preferred
    driver . execute_cdp ( 'Performance.enable' ) 
 
     metric_list  =  driver . execute_cdp ( 'Performance.getMetrics' ) [ 'metrics' ]  Basic authentication Alternate implementations can be found at CDP API Basic Authentication 
and BiDi API Basic Authentication 
Java 
Python 
CSharp 
Ruby 
JavaScript 
Kotlin The BiDi API Basic Authentication  implementation should be preferred
     (( HasCdp )   driver ). executeCdpCommand ( "Network.enable" ,   new   HashMap <> ()); 
 
      String   encodedAuth   =   Base64 . getEncoder (). encodeToString ( "admin:admin" . getBytes ()); 
      Map < String ,   Object >   headers   = 
          ImmutableMap . of ( "headers" ,   ImmutableMap . of ( "authorization" ,   "Basic "   +   encodedAuth )); 
 
      (( HasCdp )   driver ). executeCdpCommand ( "Network.setExtraHTTPHeaders" ,   headers );     driver . execute_cdp_cmd ( "Network.enable" ,  {}) 
 
     credentials  =  base64 . b64encode ( "admin:admin" . encode ()) . decode () 
     headers  =  { 'headers' :  { 'authorization' :  'Basic '  +  credentials }} 
 
     driver . execute_cdp_cmd ( 'Network.setExtraHTTPHeaders' ,  headers )              (( ChromeDriver ) driver ). ExecuteCdpCommand ( "Network.enable" ,  emptyDictionary ); 
             
             string  encodedAuth  =  Convert . ToBase64String ( Encoding . Default . GetBytes ( "admin:admin" )); 
             var  headers  =  new  Dictionary < string ,  object > 
             { 
                 {  "headers" ,  new  Dictionary < string ,  string >  {  {  "authorization" ,  "Basic "  +  encodedAuth  }  }  } 
             }; 
 
             (( ChromeDriver ) driver ). ExecuteCdpCommand ( "Network.setExtraHTTPHeaders" ,  headers );  The BiDi API Basic Authentication  implementation should be preferred
    driver . execute_cdp ( 'Network.enable' ) 
 
     credentials  =  Base64 . strict_encode64 ( 'admin:admin' ) 
     headers  =  { authorization :  "Basic  #{ credentials } " } 
 
     driver . execute_cdp ( 'Network.setExtraHTTPHeaders' ,  headers :  headers )  1.2 - Chrome DevTools Protocol API Each of the Selenium bindings dynamically generates classes and methods for the various CDP domains and features; these are tied to specific versions of Chrome.
While Selenium 4 provides direct access to the Chrome DevTools Protocol (CDP), these
methods will eventually be removed. It is recommended to use the WebDriver Bidi APIs 
methods where possible to ensure future compatibility.
Usage If your use case has been implemented by WebDriver Bidi  or
the BiDi API , you should use those implementations instead of this one.
Generally you should prefer this approach over executing with the CDP Endpoint ,
especially in Ruby.
Examples Set Cookie An alternate implementation can be found at CDP Endpoint Set Cookie 
Java 
Python 
CSharp 
Ruby 
JavaScript 
Kotlin Because Java requires using all the parameters example, the Map approach used in
CDP Endpoint Set Cookie  might be more simple.
     devTools   =   (( HasDevTools )   driver ). getDevTools (); 
      devTools . createSession (); 
 
      devTools . send ( 
          Network . setCookie ( 
              "cheese" , 
              "gouda" , 
              Optional . empty (), 
              Optional . of ( "www.selenium.dev" ), 
              Optional . empty (), 
              Optional . of ( true ), 
              Optional . empty (), 
              Optional . empty (), 
              Optional . empty (), 
              Optional . empty (), 
              Optional . empty (), 
              Optional . empty (), 
              Optional . empty (), 
              Optional . empty ())); Because Python requires using async methods for this example, the synchronous approach found in
CDP Endpoint Set Cookie  might be easier.
    async  with  driver . bidi_connection ()  as  connection : 
         execution  =  connection . devtools . network . set_cookie ( 
             name = "cheese" , 
             value = "gouda" , 
             domain = "www.selenium.dev" , 
             secure = True 
         ) 
 
         await  connection . session . execute ( execution )  Due to the added complexity in .NET of obtaining the domains and executing with awaits, the
CDP Endpoint Set Cookie  might be easier.
            var  session  =  (( IDevTools ) driver ). GetDevToolsSession (); 
             var  domains  =  session . GetVersionSpecificDomains < OpenQA . Selenium . DevTools . V124 . DevToolsSessionDomains >(); 
             await  domains . Network . Enable ( new  OpenQA . Selenium . DevTools . V124 . Network . EnableCommandSettings ()); 
 
             var  cookieCommandSettings  =  new  SetCookieCommandSettings 
             { 
                 Name  =  "cheese" , 
                 Value  =  "gouda" , 
                 Domain  =  "www.selenium.dev" , 
                 Secure  =  true 
             }; 
 
             await  domains . Network . SetCookie ( cookieCommandSettings );      driver . devtools . network . set_cookie ( name :  'cheese' , 
                                        value :  'gouda' , 
                                        domain :  'www.selenium.dev' , 
                                        secure :  true )  An alternate implementation can be found at CDP Endpoint Performance Metrics 
Java 
Python 
CSharp 
Ruby 
JavaScript 
Kotlin      devTools   =   (( HasDevTools )   driver ). getDevTools (); 
      devTools . createSession (); 
      devTools . send ( Performance . enable ( Optional . empty ())); 
 
      List < Metric >   metricList   =   devTools . send ( Performance . getMetrics ()); Because Python requires using async methods for this example, the synchronous approach found in
CDP Endpoint Performance Metrics  might be easier.
    async  with  driver . bidi_connection ()  as  connection : 
         await  connection . session . execute ( connection . devtools . performance . enable ()) 
 
         metric_list  =  await  connection . session . execute ( connection . devtools . performance . get_metrics ())  Due to the added complexity in .NET of obtaining the domains and executing with awaits, the
CDP Endpoint Performance Metrics  might be easier.
            var  session  =  (( IDevTools ) driver ). GetDevToolsSession (); 
             var  domains  =  session . GetVersionSpecificDomains < OpenQA . Selenium . DevTools . V124 . DevToolsSessionDomains >(); 
             await  domains . Performance . Enable ( new  OpenQA . Selenium . DevTools . V124 . Performance . EnableCommandSettings ()); 
 
             var  metricsResponse  = 
                 await  session . SendCommand < GetMetricsCommandSettings ,  GetMetricsCommandResponse >( 
                     new  GetMetricsCommandSettings () 
                 );      driver . devtools . performance . enable 
 
     metric_list  =  driver . devtools . performance . get_metrics . dig ( 'result' ,  'metrics' )  Basic authentication Alternate implementations can be found at
CDP Endpoint Basic Authentication 
and BiDi API Basic Authentication 
Java 
Python 
CSharp 
Ruby 
JavaScript 
Kotlin The BiDi API Basic Authentication  implementation should be preferred
     devTools   =   (( HasDevTools )   driver ). getDevTools (); 
      devTools . createSession (); 
      devTools . send ( Network . enable ( Optional . of ( 100000 ),   Optional . of ( 100000 ),   Optional . of ( 100000 ))); 
 
      String   encodedAuth   =   Base64 . getEncoder (). encodeToString ( "admin:admin" . getBytes ()); 
      Map < String ,   Object >   headers   =   ImmutableMap . of ( "Authorization" ,   "Basic "   +   encodedAuth ); 
 
      devTools . send ( Network . setExtraHTTPHeaders ( new   Headers ( headers ))); Because Python requires using async methods for this example, the synchronous approach found in
CDP Endpoint Basic Authentication  might be easier.
    async  with  driver . bidi_connection ()  as  connection : 
         await  connection . session . execute ( connection . devtools . network . enable ()) 
 
         credentials  =  base64 . b64encode ( "admin:admin" . encode ()) . decode () 
         auth  =  { 'authorization' :  'Basic '  +  credentials } 
 
         await  connection . session . execute ( connection . devtools . network . set_extra_http_headers ( Headers ( auth )))  Due to the added complexity in .NET of obtaining the domains and executing with awaits, the
CDP Endpoint Basic Authentication  might be easier.
            var  session  =  (( IDevTools ) driver ). GetDevToolsSession (); 
             var  domains  =  session . GetVersionSpecificDomains < OpenQA . Selenium . DevTools . V124 . DevToolsSessionDomains >(); 
             await  domains . Network . Enable ( new  OpenQA . Selenium . DevTools . V124 . Network . EnableCommandSettings ()); 
 
             var  encodedAuth  =  Convert . ToBase64String ( Encoding . Default . GetBytes ( "admin:admin" )); 
             var  headerSettings  =  new  SetExtraHTTPHeadersCommandSettings 
             { 
                 Headers  =  new  Headers () 
                 { 
                     {  "authorization" ,  "Basic "  +  encodedAuth  } 
                 } 
             }; 
 
             await  domains . Network . SetExtraHTTPHeaders ( headerSettings );  The BiDi API Basic Authentication  implementation should be preferred
    driver . devtools . network . enable 
 
     credentials  =  Base64 . strict_encode64 ( 'admin:admin' ) 
 
     driver . devtools . network . set_extra_http_headers ( headers :  { authorization :  "Basic  #{ credentials } " })  Console logs Because reading console logs requires setting an event listener,
this cannot be done with a CDP Endpoint implementation
Alternate implementations can be found at
BiDi API Console logs and errors 
and WebDriver BiDi Console logs 
Java 
Python 
CSharp 
Ruby 
JavaScript 
Kotlin Use the WebDriver BiDi Console logs  implementation
     DevTools   devTools   =   (( HasDevTools )   driver ). getDevTools (); 
      devTools . createSession (); 
      devTools . send ( Runtime . enable ()); 
 
      CopyOnWriteArrayList < String >   logs   =   new   CopyOnWriteArrayList <> (); 
      devTools . addListener ( 
          Runtime . consoleAPICalled (), 
          event   ->   logs . add (( String )   event . getArgs (). get ( 0 ). getValue (). orElse ( "" ))); The BiDi API Console logs and errors  implementation should be preferred
    driver . devtools . runtime . enable 
 
     logs  =  [] 
     driver . devtools . runtime . on ( :console_api_called )  do  | params | 
       logs  <<  params [ 'args' ]. first [ 'value' ] 
     end  JavaScript exceptions Similar to console logs, but this listens for actual javascript exceptions not just logged errors
Alternate implementations can be found at
BiDi API JavaScript exceptions 
and WebDriver BiDi JavaScript exceptions 
Java 
Python 
CSharp 
Ruby 
JavaScript 
Kotlin Use the WebDriver BiDi JavaScript exceptions  implementation
     DevTools   devTools   =   (( HasDevTools )   driver ). getDevTools (); 
      devTools . createSession (); 
      devTools . send ( Runtime . enable ()); 
 
      CopyOnWriteArrayList < JavascriptException >   errors   =   new   CopyOnWriteArrayList <> (); 
      devTools . getDomains (). events (). addJavascriptExceptionListener ( errors :: add ); Download complete Wait for a download to finish before continuing.
Because getting download status requires setting a listener, this cannot be done with a CDP Endpoint implementation.
Java 
Python 
CSharp 
Ruby 
JavaScript 
Kotlin      devTools   =   (( HasDevTools )   driver ). getDevTools (); 
      devTools . createSession (); 
      devTools . send ( 
          Browser . setDownloadBehavior ( 
              Browser . SetDownloadBehaviorBehavior . ALLOWANDNAME , 
              Optional . empty (), 
              Optional . of ( "" ), 
              Optional . of ( true ))); 
 
      AtomicBoolean   completed   =   new   AtomicBoolean ( false ); 
      devTools . addListener ( 
          Browser . downloadProgress (), 
          e   ->   completed . set ( Objects . equals ( e . getState (). toString (),   "completed" )));     driver . devtools . browser . set_download_behavior ( behavior :  'allow' , 
                                                   download_path :  '' , 
                                                   events_enabled :  true ) 
 
     driver . devtools . browser . on ( :download_progress )  do  | progress | 
       @completed  =  progress [ 'state' ]  ==  'completed' 
     end  1.3 - Chrome Devtools Protocol with BiDi API These examples are currently implemented with CDP, but the same code should work when the functionality is re-implemented with WebDriver-BiDi.
Usage The following list of APIs will be growing as the Selenium
project works through supporting real world use cases. If there
is additional functionality you’d like to see, please raise a
feature request .
As these examples are re-implemented with the WebDriver-Bidi  protocol, they will
be moved to the WebDriver Bidi  pages.
Examples Basic authentication Some applications make use of browser authentication to secure pages.
It used to be common to handle them in the URL, but browser stopped supporting this.
With BiDi, you can now provide the credentials when necessary
Alternate implementations can be found at
CDP Endpoint Basic Authentication 
and CDP API Basic Authentication 
Java 
Python 
CSharp 
Ruby 
JavaScript 
Kotlin      Predicate < URI >   uriPredicate   =   uri   ->   uri . toString (). contains ( "herokuapp.com" ); 
      Supplier < Credentials >   authentication   =   UsernameAndPassword . of ( "admin" ,   "admin" ); 
 
      (( HasAuthentication )   driver ). register ( uriPredicate ,   authentication );             var  handler  =  new  NetworkAuthenticationHandler () 
             { 
                 UriMatcher  =  uri  =>  uri . AbsoluteUri . Contains ( "herokuapp" ), 
                 Credentials  =  new  PasswordCredentials ( "admin" ,  "admin" ) 
             }; 
 
             var  networkInterceptor  =  driver . Manage (). Network ; 
             networkInterceptor . AddAuthenticationHandler ( handler ); 
 
             await  networkInterceptor . StartMonitoring ();      driver . register ( username :  'admin' , 
                     password :  'admin' , 
                     uri :  /herokuapp/ )  Move Code 
const  { Builder }  =  require ( 'selenium-webdriver' ); 
 ( async  function  example ()  { 
  try  { 
     let  driver  =  await  new  Builder () 
       . forBrowser ( 'chrome' ) 
       . build (); 
 
     const  pageCdpConnection  =  await  driver . createCDPConnection ( 'page' ); 
     await  driver . register ( 'username' ,  'password' ,  pageCdpConnection ); 
     await  driver . get ( 'https://the-internet.herokuapp.com/basic_auth' ); 
     await  driver . quit (); 
   } catch  ( e ){ 
     console . log ( e ) 
   } 
 }()) 
Move Code 
val   uriPredicate   =   Predicate   {   uri :   URI   -> 
          uri . host . contains ( "your-domain.com" ) 
      } 
 ( driver   as   HasAuthentication ). register ( uriPredicate ,   UsernameAndPassword . of ( "admin" ,   "password" )) 
 driver . get ( "https://your-domain.com/login" ) 
 Pin scripts This can be especially useful when executing on a remote server. For example,
whenever you check the visibility of an element, or whenever you use
the classic get attribute method, Selenium is sending the contents of a js file
to the script execution endpoint. These files are each about 50kB, which adds up.
Java 
Python 
CSharp 
Ruby 
JavaScript 
Kotlin             var  key  =  await  new  JavaScriptEngine ( driver ). PinScript ( "return arguments;" ); 
 
             var  arguments  =  (( WebDriver ) driver ). ExecuteScript ( key ,  1 ,  true ,  element );      key  =  driver . pin_script ( 'return arguments;' ) 
     arguments  =  driver . execute_script ( key ,  1 ,  true ,  element )  Mutation observation Mutation Observation is the ability to capture events via
WebDriver BiDi when there are DOM mutations on a specific
element in the DOM.
Java 
Python 
CSharp 
Ruby 
JavaScript 
Kotlin      CopyOnWriteArrayList < WebElement >   mutations   =   new   CopyOnWriteArrayList <> (); 
      (( HasLogEvents )   driver ). onLogEvent ( domMutation ( e   ->   mutations . add ( e . getElement ())));     async  with  driver . bidi_connection ()  as  session : 
         log  =  Log ( driver ,  session ) 
             var  mutations  =  new  List < IWebElement >(); 
             using  IJavaScriptEngine  monitor  =  new  JavaScriptEngine ( driver ); 
             monitor . DomMutated  +=  ( _ ,  e )  => 
             { 
                 var  locator  =  By . CssSelector ( $"*[data-__webdriver_id='{e.AttributeData.TargetId}']" ); 
                 mutations . Add ( driver . FindElement ( locator )); 
             }; 
 
             await  monitor . StartEventMonitoring (); 
             await  monitor . EnableDomMutationMonitoring ();      mutations  =  [] 
     driver . on_log_event ( :mutation )  {  | mutation |  mutations  <<  mutation . element  }  Move Code 
const  { Builder ,  until }  =  require ( 'selenium-webdriver' ); 
const  assert  =  require ( "assert" ); 
 ( async  function  example ()  { 
  try  { 
     let  driver  =  await  new  Builder () 
       . forBrowser ( 'chrome' ) 
       . build (); 
 
     const  cdpConnection  =  await  driver . createCDPConnection ( 'page' ); 
     await  driver . logMutationEvents ( cdpConnection ,  event  =>  { 
       assert . deepStrictEqual ( event [ 'attribute_name' ],  'style' ); 
       assert . deepStrictEqual ( event [ 'current_value' ],  "" ); 
       assert . deepStrictEqual ( event [ 'old_value' ],  "display:none;" ); 
     }); 
 
     await  driver . get ( 'dynamic.html' ); 
     await  driver . findElement ({ id :  'reveal' }). click (); 
     let  revealed  =  driver . findElement ({ id :  'revealed' }); 
     await  driver . wait ( until . elementIsVisible ( revealed ),  5000 ); 
     await  driver . quit (); 
   } catch  ( e ){ 
     console . log ( e ) 
   } 
 }()) 
Console logs and errors Listen to the console.log events and register callbacks to process the event.
CDP API Console logs 
and WebDriver BiDi Console logs 
Java 
Python 
CSharp 
Ruby 
JavaScript 
Kotlin Use the WebDriver BiDi Console logs  implementation. HasLogEvents
will likely end up deprecated because it does not implement Closeable.
     CopyOnWriteArrayList < String >   messages   =   new   CopyOnWriteArrayList <> (); 
      (( HasLogEvents )   driver ). onLogEvent ( consoleEvent ( e   ->   messages . add ( e . getMessages (). get ( 0 ))));     async  with  driver . bidi_connection ()  as  session : 
         log  =  Log ( driver ,  session ) 
 
         async  with  log . add_listener ( Console . ALL )  as  messages :              using  IJavaScriptEngine  monitor  =  new  JavaScriptEngine ( driver ); 
             var  messages  =  new  List < string >(); 
             monitor . JavaScriptConsoleApiCalled  +=  ( _ ,  e )  => 
             { 
                 messages . Add ( e . MessageContent ); 
             }; 
 
             await  monitor . StartEventMonitoring ();      logs  =  [] 
     driver . on_log_event ( :console )  {  | log |  logs  <<  log . args . first  }  Move Code 
const  { Builder }  =  require ( 'selenium-webdriver' ); 
( async  ()  =>  { 
  try  { 
     let  driver  =  new  Builder () 
       . forBrowser ( 'chrome' ) 
       . build (); 
 
     const  cdpConnection  =  await  driver . createCDPConnection ( 'page' ); 
     await  driver . onLogEvent ( cdpConnection ,  function  ( event )  { 
       console . log ( event [ 'args' ][ 0 ][ 'value' ]); 
     }); 
     await  driver . executeScript ( 'console.log("here")' ); 
     await  driver . quit (); 
   } catch  ( e ){ 
     console . log ( e ); 
   } 
 })() 
Move Code 
fun   kotlinConsoleLogExample ()   { 
      val   driver   =   ChromeDriver () 
      val   devTools   =   driver . devTools 
      devTools . createSession () 
 
      val   logConsole   =   {   c :   ConsoleEvent   ->   print ( "Console log message is: "   +   c . messages )} 
      devTools . domains . events (). addConsoleListener ( logConsole ) 
 
      driver . get ( "https://www.google.com" ) 
 
      val   executor   =   driver   as   JavascriptExecutor 
      executor . executeScript ( "console.log('Hello World')" ) 
 
      val   input   =   driver . findElement ( By . name ( "q" )) 
      input . sendKeys ( "Selenium 4" ) 
      input . sendKeys ( Keys . RETURN ) 
      driver . quit () 
 } 
 JavaScript exceptions Listen to the JS Exceptions
and register callbacks to process the exception details.
Java 
Python 
CSharp 
Ruby 
JavaScript 
Kotlin     async  with  driver . bidi_connection ()  as  session : 
         log  =  Log ( driver ,  session ) 
 
         async  with  log . add_js_error_listener ()  as  messages :              using  IJavaScriptEngine  monitor  =  new  JavaScriptEngine ( driver ); 
             var  messages  =  new  List < string >(); 
             monitor . JavaScriptExceptionThrown  +=  ( _ ,  e )  => 
             { 
                 messages . Add ( e . Message ); 
             }; 
 
             await  monitor . StartEventMonitoring ();      exceptions  =  [] 
     driver . on_log_event ( :exception )  {  | exception |  exceptions  <<  exception  }  Network Interception Both requests and responses can be recorded or transformed.
Java 
Python 
CSharp 
Ruby 
JavaScript 
Kotlin      CopyOnWriteArrayList < String >   contentType   =   new   CopyOnWriteArrayList <> (); 
 
      try   ( NetworkInterceptor   ignored   = 
          new   NetworkInterceptor ( 
              driver , 
              ( Filter ) 
                  next   -> 
                      req   ->   { 
                        HttpResponse   res   =   next . execute ( req ); 
                        contentType . add ( res . getHeader ( "Content-Type" )); 
                        return   res ; 
                      }))   {             var  contentType  =  new  List < string >(); 
 
             INetwork  networkInterceptor  =  driver . Manage (). Network ; 
             networkInterceptor . NetworkResponseReceived  +=  ( _ ,  e )   => 
             { 
                 contentType . Add ( e . ResponseHeaders [ "content-type" ]); 
             }; 
 
             await  networkInterceptor . StartMonitoring ();      content_type  =  [] 
     driver . intercept  do  | request ,  & continue | 
       continue . call ( request )  do  | response | 
         content_type  <<  response . headers [ 'content-type' ] 
       end 
     end  
Java 
Python 
CSharp 
Ruby 
JavaScript 
Kotlin      try   ( NetworkInterceptor   ignored   = 
          new   NetworkInterceptor ( 
              driver , 
              Route . matching ( req   ->   true ) 
                  . to ( 
                      ()   -> 
                          req   -> 
                              new   HttpResponse () 
                                  . setStatus ( 200 ) 
                                  . addHeader ( "Content-Type" ,   MediaType . HTML_UTF_8 . toString ()) 
                                  . setContent ( Contents . utf8String ( "Creamy, delicious cheese!" )))))   {             var  handler  =  new  NetworkResponseHandler () 
             { 
                 ResponseMatcher  =  _  =>  true , 
                 ResponseTransformer  =  _  =>  new  HttpResponseData 
                 { 
                     StatusCode  =  200 , 
                     Body  =  "Creamy, delicious cheese!" 
                 } 
             }; 
 
             INetwork  networkInterceptor  =  driver . Manage (). Network ; 
             networkInterceptor . AddResponseHandler ( handler ); 
 
             await  networkInterceptor . StartMonitoring ();      driver . intercept  do  | request ,  & continue | 
       continue . call ( request )  do  | response | 
         response . body  =  'Creamy, delicious cheese!'  if  request . url . include? ( 'blank' ) 
       end 
     end  Move Code 
const  connection  =  await  driver . createCDPConnection ( 'page' ) 
let  url  =  fileServer . whereIs ( "/cheese" ) 
let  httpResponse  =  new  HttpResponse ( url ) 
httpResponse . addHeaders ( "Content-Type" ,  "UTF-8" ) 
httpResponse . body  =  "sausages" 
await  driver . onIntercept ( connection ,  httpResponse ,  async  function  ()  { 
  let  body  =  await  driver . getPageSource () 
   assert . strictEqual ( body . includes ( "sausages" ),  true ,  `Body contains:  ${ body } ` ) 
 }) 
driver . get ( url ) 
Move Code 
val   driver   =   ChromeDriver () 
 val   interceptor   =   new   NetworkInterceptor ( 
        driver , 
        Route . matching ( req   ->   true ) 
          . to (()   ->   req   ->   new   HttpResponse () 
            . setStatus ( 200 ) 
            . addHeader ( "Content-Type" ,   MediaType . HTML_UTF_8 . toString ()) 
            . setContent ( utf8String ( "Creamy, delicious cheese!" )))) 
 
      driver . get ( appServer . whereIs ( "/cheese" )) 
 
      String   source   =   driver . getPageSource () 
 Request interception 
Java 
Python 
CSharp 
Ruby 
JavaScript 
Kotlin             var  handler  =  new  NetworkRequestHandler 
             { 
                 RequestMatcher  =  request  =>  request . Url . Contains ( "one.js" ), 
                 RequestTransformer  =  request  => 
                 { 
                     request . Url  =  request . Url . Replace ( "one" ,  "two" ); 
 
                     return  request ; 
                 } 
             }; 
 
             INetwork  networkInterceptor  =  driver . Manage (). Network ; 
             networkInterceptor . AddRequestHandler ( handler ); 
 
             await  networkInterceptor . StartMonitoring ();      driver . intercept  do  | request ,  & continue | 
       uri  =  URI ( request . url ) 
       request . url  =  uri . to_s . gsub ( 'one' ,  'two' )  if  uri . path &. end_with? ( 'one.js' ) 
       continue . call ( request ) 
     end  2 - BiDirectional API (W3C compliant) The following list of APIs will be growing as the WebDriver BiDirectional Protocol  grows
and browser vendors implement the same.
Additionally, Selenium will try to support real-world use cases that internally use a combination of W3C BiDi protocol APIs.
If there is additional functionality you’d like to see, please raise a
feature request .
2.1 - Browsing Context 
Commands This section contains the APIs related to browsing context commands.
Open a new window Creates a new browsing context in a new window.
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.8 
     void   testCreateAWindow ()   { 
          BrowsingContext   browsingContext   =   new   BrowsingContext ( driver ,   WindowType . WINDOW ); 
          Assertions . assertNotNull ( browsingContext . getId ()); 
      } Selenium v4.8 
            const  browsingContext  =  await  BrowsingContext ( driver ,  { 
                 type :  'window' , 
             })  Open a new tab Creates a new browsing context in a new tab.
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.8 
     void   testCreateATab ()   { 
          BrowsingContext   browsingContext   =   new   BrowsingContext ( driver ,   WindowType . TAB ); 
          Assertions . assertNotNull ( browsingContext . getId ()); 
      } Selenium v4.8 
            const  browsingContext  =  await  BrowsingContext ( driver ,  { 
                 type :  'tab' , 
             })  Use existing window handle Creates a browsing context for the existing tab/window to run commands.
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.8 
     void   testCreateABrowsingContextForGivenId ()   { 
          String   id   =   driver . getWindowHandle (); 
          BrowsingContext   browsingContext   =   new   BrowsingContext ( driver ,   id ); 
          Assertions . assertEquals ( id ,   browsingContext . getId ()); 
      } Selenium v4.8 
            const  id  =  await  driver . getWindowHandle () 
             const  browsingContext  =  await  BrowsingContext ( driver ,  { 
                 browsingContextId :  id , 
             })  Open a window with a reference browsing context A reference browsing context is a top-level browsing context .
The API allows to pass the reference browsing context, which is used to create a new window. The implementation is operating system specific.
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.8 
     void   testCreateAWindowWithAReferenceContext ()   { 
          BrowsingContext 
                  browsingContext   = 
                  new   BrowsingContext ( driver ,   WindowType . WINDOW ,   driver . getWindowHandle ()); 
          Assertions . assertNotNull ( browsingContext . getId ()); 
      } Selenium v4.8 
            const  browsingContext  =  await  BrowsingContext ( driver ,  { 
                 type :  'window' , 
                 referenceContext :  await  driver . getWindowHandle (), 
             })  Open a tab with a reference browsing context A reference browsing context is a top-level browsing context .
The API allows to pass the reference browsing context, which is used to create a new tab. The implementation is operating system specific.
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.8 
     void   testCreateATabWithAReferenceContext ()   { 
          BrowsingContext 
                  browsingContext   = 
                  new   BrowsingContext ( driver ,   WindowType . TAB ,   driver . getWindowHandle ()); 
          Assertions . assertNotNull ( browsingContext . getId ()); 
      } Selenium v4.8 
            const  browsingContext  =  await  BrowsingContext ( driver ,  { 
                 type :  'tab' , 
                 referenceContext :  await  driver . getWindowHandle (), 
             })  Navigate to a URL 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.8 
     void   testNavigateToAUrl ()   { 
          BrowsingContext   browsingContext   =   new   BrowsingContext ( driver ,   WindowType . TAB ); 
 
          NavigationResult   info   =   browsingContext . navigate ( "https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html" ); 
 
          Assertions . assertNotNull ( browsingContext . getId ()); 
          Assertions . assertNotNull ( info . getNavigationId ()); 
          Assertions . assertTrue ( info . getUrl (). contains ( "/bidi/logEntryAdded.html" )); 
      } Selenium v4.8 
            let  info  =  await  browsingContext . navigate ( 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html' )  Navigate to a URL with readiness state 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.8 
     void   testNavigateToAUrlWithReadinessState ()   { 
          BrowsingContext   browsingContext   =   new   BrowsingContext ( driver ,   WindowType . TAB ); 
 
          NavigationResult   info   =   browsingContext . navigate ( "https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html" , 
                  ReadinessState . COMPLETE ); 
 
          Assertions . assertNotNull ( browsingContext . getId ()); 
          Assertions . assertNotNull ( info . getNavigationId ()); 
          Assertions . assertTrue ( info . getUrl (). contains ( "/bidi/logEntryAdded.html" )); 
      } Selenium v4.8 
            const  info  =  await  browsingContext . navigate ( 
                 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html' , 
                 'complete' 
             )  Get browsing context tree Provides a tree of all browsing contexts descending from the parent browsing context, including the parent browsing context.
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.8 
     void   testGetTreeWithAChild ()   { 
          String   referenceContextId   =   driver . getWindowHandle (); 
          BrowsingContext   parentWindow   =   new   BrowsingContext ( driver ,   referenceContextId ); 
 
          parentWindow . navigate ( "https://www.selenium.dev/selenium/web/iframes.html" ,   ReadinessState . COMPLETE ); 
 
          List < BrowsingContextInfo >   contextInfoList   =   parentWindow . getTree (); 
 
          Assertions . assertEquals ( 1 ,   contextInfoList . size ()); 
          BrowsingContextInfo   info   =   contextInfoList . get ( 0 ); 
          Assertions . assertEquals ( 1 ,   info . getChildren (). size ()); 
          Assertions . assertEquals ( referenceContextId ,   info . getId ()); 
          Assertions . assertTrue ( info . getChildren (). get ( 0 ). getUrl (). contains ( "formPage.html" )); 
      } Selenium v4.8 
            const  browsingContextId  =  await  driver . getWindowHandle () 
             const  parentWindow  =  await  BrowsingContext ( driver ,  { 
                 browsingContextId :  browsingContextId , 
             }) 
             await  parentWindow . navigate ( 'https://www.selenium.dev/selenium/web/iframes.html' ,  'complete' ) 
 
             const  contextInfo  =  await  parentWindow . getTree ()  Get browsing context tree with depth Provides a tree of all browsing contexts descending from the parent browsing context, including the parent browsing context upto the depth value passed.
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.8 
     void   testGetTreeWithDepth ()   { 
          String   referenceContextId   =   driver . getWindowHandle (); 
          BrowsingContext   parentWindow   =   new   BrowsingContext ( driver ,   referenceContextId ); 
 
          parentWindow . navigate ( "https://www.selenium.dev/selenium/web/iframes.html" ,   ReadinessState . COMPLETE ); 
 
          List < BrowsingContextInfo >   contextInfoList   =   parentWindow . getTree ( 0 ); 
 
          Assertions . assertEquals ( 1 ,   contextInfoList . size ()); 
          BrowsingContextInfo   info   =   contextInfoList . get ( 0 ); 
          Assertions . assertNull ( info . getChildren ());   // since depth is 0 
          Assertions . assertEquals ( referenceContextId ,   info . getId ()); 
      } Selenium v4.8 
            const  browsingContextId  =  await  driver . getWindowHandle () 
             const  parentWindow  =  await  BrowsingContext ( driver ,  { 
                 browsingContextId :  browsingContextId , 
             }) 
             await  parentWindow . navigate ( 'https://www.selenium.dev/selenium/web/iframes.html' ,  'complete' ) 
 
             const  contextInfo  =  await  parentWindow . getTree ( 0 )  Get All Top level browsing contexts 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.8 
     void   testGetAllTopLevelContexts ()   { 
          BrowsingContext   window1   =   new   BrowsingContext ( driver ,   driver . getWindowHandle ()); 
          BrowsingContext   window2   =   new   BrowsingContext ( driver ,   WindowType . WINDOW ); 
 
          List < BrowsingContextInfo >   contextInfoList   =   window1 . getTopLevelContexts (); 
 
          Assertions . assertEquals ( 2 ,   contextInfoList . size ()); 
      } Selenium v4.20.0 
            const  id  =  await  driver . getWindowHandle () 
             const  window1  =  await  BrowsingContext ( driver ,  { 
                 browsingContextId :  id , 
             }) 
             await  BrowsingContext ( driver ,  {  type :  'window'  }) 
             const  res  =  await  window1 . getTopLevelContexts ()  Close a tab/window 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.8 
     void   testCloseAWindow ()   { 
          BrowsingContext   window1   =   new   BrowsingContext ( driver ,   WindowType . WINDOW ); 
          BrowsingContext   window2   =   new   BrowsingContext ( driver ,   WindowType . WINDOW ); 
 
          window2 . close (); 
 
          Assertions . assertThrows ( BiDiException . class ,   window2 :: getTree ); 
      } 
 
      @Test 
      void   testCloseATab ()   { 
          BrowsingContext   tab1   =   new   BrowsingContext ( driver ,   WindowType . TAB ); 
          BrowsingContext   tab2   =   new   BrowsingContext ( driver ,   WindowType . TAB ); 
 
          tab2 . close (); 
 
          Assertions . assertThrows ( BiDiException . class ,   tab2 :: getTree ); 
      } Selenium v4.8 
            const  window1  =  await  BrowsingContext ( driver ,  { type :  'window' }) 
             const  window2  =  await  BrowsingContext ( driver ,  { type :  'window' }) 
 
             await  window2 . close ()  Activate a browsing context 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.14.1 
         BrowsingContext   window1   =   new   BrowsingContext ( driver ,   driver . getWindowHandle ()); 
          BrowsingContext   window2   =   new   BrowsingContext ( driver ,   WindowType . WINDOW ); 
 
          window1 . activate (); 
 Selenium v4.15 
            const  window1  =  await  BrowsingContext ( driver ,  { 
                 browsingContextId :  id , 
             }) 
 
             await  BrowsingContext ( driver ,  { 
                 type :  'window' , 
             }) 
 
             const  result  =  await  driver . executeScript ( 'return document.hasFocus();' ) 
 
             assert . equal ( result ,  false ) 
 
             await  window1 . activate ()  Reload a browsing context 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.13.0 
         BrowsingContext   browsingContext   =   new   BrowsingContext ( driver ,   WindowType . TAB ); 
 
          browsingContext . navigate ( "https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html" ,   ReadinessState . COMPLETE ); 
 
          NavigationResult   reloadInfo   =   browsingContext . reload ( ReadinessState . INTERACTIVE ); Selenium v4.15 
            await  browsingContext . reload ( undefined ,  'complete' )  Handle user prompt 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.13.0 
         BrowsingContext   browsingContext   =   new   BrowsingContext ( driver ,   driver . getWindowHandle ()); 
 
          driver . get ( "https://www.selenium.dev/selenium/web/alerts.html" ); 
 
          driver . findElement ( By . id ( "prompt-with-default" )). click (); 
 
          String   userText   =   "Selenium automates browsers" ; 
          browsingContext . handleUserPrompt ( true ,   userText ); 
 Selenium v4.15 
            await  browsingContext . handleUserPrompt ( true ,  userText )  Capture Screenshot 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.13.0 
         BrowsingContext   browsingContext   =   new   BrowsingContext ( driver ,   driver . getWindowHandle ()); 
 
          driver . get ( "https://www.selenium.dev/selenium/web/alerts.html" ); 
 
          String   screenshot   =   browsingContext . captureScreenshot (); Selenium v4.15 
            const  response  =  await  browsingContext . captureScreenshot ()  Capture Viewport Screenshot 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.14.0 
         BrowsingContext   browsingContext   =   new   BrowsingContext ( driver ,   driver . getWindowHandle ()); 
 
          driver . get ( "https://www.selenium.dev/selenium/web/coordinates_tests/simple_page.html" ); 
 
          WebElement   element   =   driver . findElement ( By . id ( "box" )); 
          Rectangle   elementRectangle   =   element . getRect (); 
 
          String   screenshot   = 
                  browsingContext . captureBoxScreenshot ( 
                          elementRectangle . getX (),   elementRectangle . getY (),   5 ,   5 ); Selenium v4.15 
            const  browsingContext  =  await  BrowsingContext ( driver ,  { 
                 browsingContextId :  id , 
             }) 
 
             const  response  =  await  browsingContext . captureBoxScreenshot ( 5 ,  5 ,  10 ,  10 )  Capture Element Screenshot 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.14.0 
         BrowsingContext   browsingContext   =   new   BrowsingContext ( driver ,   driver . getWindowHandle ()); 
 
          driver . get ( "https://www.selenium.dev/selenium/web/formPage.html" ); 
          WebElement   element   =   driver . findElement ( By . id ( "checky" )); 
 
          String   screenshot   =   browsingContext . captureElementScreenshot ((( RemoteWebElement )   element ). getId ()); Selenium v4.15 
            const  response  =  await  browsingContext . captureElementScreenshot ( elementId )  Set Viewport 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.14.1 
         BrowsingContext   browsingContext   =   new   BrowsingContext ( driver ,   driver . getWindowHandle ()); 
          driver . get ( "https://www.selenium.dev/selenium/web/formPage.html" ); 
 
          browsingContext . setViewport ( 250 ,   300 ,   5 ); Selenium v4.15 
            await  browsingContext . setViewport ( 250 ,  300 )  Print page 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.14.1 
         BrowsingContext   browsingContext   =   new   BrowsingContext ( driver ,   driver . getWindowHandle ()); 
 
          driver . get ( "https://www.selenium.dev/selenium/web/formPage.html" ); 
          PrintOptions   printOptions   =   new   PrintOptions (); 
 
          String   printPage   =   browsingContext . print ( printOptions ); Selenium v4.10 
            const  result  =  await  browsingContext . printPage ({ 
                 orientation :  'landscape' , 
                 scale :  1 , 
                 background :  true , 
                 width :  30 , 
                 height :  30 , 
                 top :  1 , 
                 bottom :  1 , 
                 left :  1 , 
                 right :  1 , 
                 shrinkToFit :  true , 
                 pageRanges :  [ '1-2' ], 
             })  Navigate back 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.16.0 
         BrowsingContext   browsingContext   =   new   BrowsingContext ( driver ,   driver . getWindowHandle ()); 
          browsingContext . navigate ( "https://www.selenium.dev/selenium/web/formPage.html" ,   ReadinessState . COMPLETE ); 
 
          wait . until ( visibilityOfElementLocated ( By . id ( "imageButton" ))). submit (); 
          wait . until ( titleIs ( "We Arrive Here" )); 
 
          browsingContext . back (); Selenium v4.17 
            await  browsingContext . back ()  Navigate forward 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.16.0 
     void   canNavigateForwardInTheBrowserHistory ()   { 
          BrowsingContext   browsingContext   =   new   BrowsingContext ( driver ,   driver . getWindowHandle ()); 
          browsingContext . navigate ( "https://www.selenium.dev/selenium/web/formPage.html" ,   ReadinessState . COMPLETE ); 
 
          wait . until ( visibilityOfElementLocated ( By . id ( "imageButton" ))). submit (); 
          wait . until ( titleIs ( "We Arrive Here" )); 
 
          browsingContext . back (); 
          Assertions . assertTrue ( driver . getPageSource (). contains ( "We Leave From Here" )); 
 
          browsingContext . forward (); Selenium v4.17 
            await  browsingContext . forward ()  Traverse history 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.16.0 
         BrowsingContext   browsingContext   =   new   BrowsingContext ( driver ,   driver . getWindowHandle ()); 
          browsingContext . navigate ( "https://www.selenium.dev/selenium/web/formPage.html" ,   ReadinessState . COMPLETE ); 
 
          wait . until ( visibilityOfElementLocated ( By . id ( "imageButton" ))). submit (); 
          wait . until ( titleIs ( "We Arrive Here" )); 
 
          browsingContext . traverseHistory ( - 1 ); Selenium v4.17 
            await  browsingContext . traverseHistory ( - 1 )  Events This section contains the APIs related to browsing context events.
Browsing Context Created Event 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.10 
     try   ( BrowsingContextInspector   inspector   =   new   BrowsingContextInspector ( driver ))   { 
          CompletableFuture < BrowsingContextInfo >   future   =   new   CompletableFuture <> (); 
 
          inspector . onBrowsingContextCreated ( future :: complete ); 
 
          String   windowHandle   =   driver . switchTo (). newWindow ( WindowType . WINDOW ). getWindowHandle (); 
 
          BrowsingContextInfo   browsingContextInfo   =   future . get ( 5 ,   TimeUnit . SECONDS ); Selenium v4.9.2 
            const  browsingContextInspector  =  await  BrowsingContextInspector ( driver ) 
             await  browsingContextInspector . onBrowsingContextCreated (( entry )  =>  { 
                 contextInfo  =  entry 
             }) 
 
             await  driver . switchTo (). newWindow ( 'window' )  Dom Content loaded Event 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.10 
             String   windowHandle   =   driver . switchTo (). newWindow ( WindowType . TAB ). getWindowHandle (); 
 
              BrowsingContextInfo   browsingContextInfo   =   future . get ( 5 ,   TimeUnit . SECONDS ); 
 
              Assertions . assertEquals ( windowHandle ,   browsingContextInfo . getId ()); 
          } 
      } 
 
      @Test 
      void   canListenToDomContentLoadedEvent () Selenium v4.9.2 
            const  browsingContextInspector  =  await  BrowsingContextInspector ( driver ) 
             let  navigationInfo  =  null 
             await  browsingContextInspector . onDomContentLoaded (( entry )  =>  { 
                 navigationInfo  =  entry 
             }) 
 
             const  browsingContext  =  await  BrowsingContext ( driver ,  { 
                 browsingContextId :  await  driver . getWindowHandle (), 
             }) 
             await  browsingContext . navigate ( 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html' ,  'complete' )  Browsing Context Loaded Event 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.10 
         try   ( BrowsingContextInspector   inspector   =   new   BrowsingContextInspector ( driver ))   { 
              CompletableFuture < NavigationInfo >   future   =   new   CompletableFuture <> (); 
              inspector . onBrowsingContextLoaded ( future :: complete ); 
 
              BrowsingContext   context   =   new   BrowsingContext ( driver ,   driver . getWindowHandle ()); 
              context . navigate ( "https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html" ,   ReadinessState . COMPLETE ); 
 
              NavigationInfo   navigationInfo   =   future . get ( 5 ,   TimeUnit . SECONDS ); Selenium v4.9.2 
            const  browsingContextInspector  =  await  BrowsingContextInspector ( driver ) 
 
             await  browsingContextInspector . onBrowsingContextLoaded (( entry )  =>  { 
                 navigationInfo  =  entry 
             }) 
             const  browsingContext  =  await  BrowsingContext ( driver ,  { 
                 browsingContextId :  await  driver . getWindowHandle (), 
             }) 
             await  browsingContext . navigate ( 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html' ,  'complete' )  Navigated Started Event 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.15 
         try   ( BrowsingContextInspector   inspector   =   new   BrowsingContextInspector ( driver ))   { 
              CompletableFuture < NavigationInfo >   future   =   new   CompletableFuture <> (); 
              inspector . onNavigationStarted ( future :: complete ); 
 
              BrowsingContext   context   =   new   BrowsingContext ( driver ,   driver . getWindowHandle ()); 
              context . navigate ( "https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html" ,   ReadinessState . COMPLETE ); 
 
              NavigationInfo   navigationInfo   =   future . get ( 5 ,   TimeUnit . SECONDS ); Fragment Navigated Event 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.15 
         try   ( BrowsingContextInspector   inspector   =   new   BrowsingContextInspector ( driver ))   { 
              CompletableFuture < NavigationInfo >   future   =   new   CompletableFuture <> (); 
 
              BrowsingContext   context   =   new   BrowsingContext ( driver ,   driver . getWindowHandle ()); 
              context . navigate ( "https://www.selenium.dev/selenium/web/linked_image.html" ,   ReadinessState . COMPLETE ); 
 
              inspector . onFragmentNavigated ( future :: complete ); 
 
              context . navigate ( "https://www.selenium.dev/selenium/web/linked_image.html#linkToAnchorOnThisPage" ,   ReadinessState . COMPLETE ); 
 
              NavigationInfo   navigationInfo   =   future . get ( 5 ,   TimeUnit . SECONDS ); Selenium v4.15.0 
            const  browsingContextInspector  =  await  BrowsingContextInspector ( driver ) 
 
             const  browsingContext  =  await  BrowsingContext ( driver ,  { 
                 browsingContextId :  await  driver . getWindowHandle (), 
             }) 
             await  browsingContext . navigate ( 'https://www.selenium.dev/selenium/web/linked_image.html' ,  'complete' ) 
 
             await  browsingContextInspector . onFragmentNavigated (( entry )  =>  { 
                 navigationInfo  =  entry 
             }) 
 
             await  browsingContext . navigate ( 'https://www.selenium.dev/selenium/web/linked_image.html#linkToAnchorOnThisPage' ,  'complete' )  User Prompt Opened Event 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.15 
         try   ( BrowsingContextInspector   inspector   =   new   BrowsingContextInspector ( driver ))   { 
              CompletableFuture < NavigationInfo >   future   =   new   CompletableFuture <> (); 
 
              BrowsingContext   context   =   new   BrowsingContext ( driver ,   driver . getWindowHandle ()); 
              context . navigate ( "https://www.selenium.dev/selenium/web/linked_image.html" ,   ReadinessState . COMPLETE ); 
 
              inspector . onFragmentNavigated ( future :: complete ); 
 
              context . navigate ( "https://www.selenium.dev/selenium/web/linked_image.html#linkToAnchorOnThisPage" ,   ReadinessState . COMPLETE ); 
 
              NavigationInfo   navigationInfo   =   future . get ( 5 ,   TimeUnit . SECONDS ); User Prompt Closed Event 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.15 
         try   ( BrowsingContextInspector   inspector   =   new   BrowsingContextInspector ( driver ))   { 
              CompletableFuture < UserPromptClosed >   future   =   new   CompletableFuture <> (); 
 
              BrowsingContext   context   =   new   BrowsingContext ( driver ,   driver . getWindowHandle ()); 
              inspector . onUserPromptClosed ( future :: complete ); 
 
              driver . get ( "https://www.selenium.dev/selenium/web/alerts.html" ); 
 
              driver . findElement ( By . id ( "prompt" )). click (); 
 
              context . handleUserPrompt ( true ,   "selenium" ); 
 
              UserPromptClosed   userPromptClosed   =   future . get ( 5 ,   TimeUnit . SECONDS ); 
              Assertions . assertEquals ( context . getId (),   userPromptClosed . getBrowsingContextId ()); Browsing Context Destroyed Event 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.18 
         try   ( BrowsingContextInspector   inspector   =   new   BrowsingContextInspector ( driver ))   { 
              CompletableFuture < BrowsingContextInfo >   future   =   new   CompletableFuture <> (); 
 
              inspector . onBrowsingContextDestroyed ( future :: complete ); 
 
              String   windowHandle   =   driver . switchTo (). newWindow ( WindowType . WINDOW ). getWindowHandle (); 
 
              driver . close (); 
 
              BrowsingContextInfo   browsingContextInfo   =   future . get ( 5 ,   TimeUnit . SECONDS ); 
 
              Assertions . assertEquals ( windowHandle ,   browsingContextInfo . getId ()); Selenium v4.18.0 
            const  browsingContextInspector  =  await  BrowsingContextInspector ( driver ) 
             await  browsingContextInspector . onBrowsingContextDestroyed (( entry )  =>  { 
                 contextInfo  =  entry 
             }) 
 
             await  driver . switchTo (). newWindow ( 'window' ) 
 
             const  windowHandle  =  await  driver . getWindowHandle () 
             await  driver . close ()  2.2 - Browsing Context 
This section contains the APIs related to input commands.
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.17 
         Actions   selectThreeOptions   = 
                  actions . click ( options . get ( 1 )). keyDown ( Keys . SHIFT ). click ( options . get ( 3 )). keyUp ( Keys . SHIFT ); 
 
          input . perform ( windowHandle ,   selectThreeOptions . getSequences ()); Selenium v4.17 
            const  actions  =  driver . actions (). click ( options [ 1 ]). keyDown ( Key . SHIFT ). click ( options [ 3 ]). keyUp ( Key . SHIFT ). getSequences () 
 
             await  input . perform ( browsingContextId ,  actions )  Release Actions 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.17 
         Actions   sendLowercase   = 
                  new   Actions ( driver ). keyDown ( inputTextBox ,   "a" ). keyDown ( inputTextBox ,   "b" ); 
 
          input . perform ( windowHandle ,   sendLowercase . getSequences ()); 
          (( JavascriptExecutor )   driver ). executeScript ( "resetEvents()" ); 
 
          input . release ( windowHandle ); Selenium v4.17 
            await  input . release ( browsingContextId )  2.3 - Network 
Commands This section contains the APIs related to network commands.
Add network intercept 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.18 
         try   ( Network   network   =   new   Network ( driver ))   { 
              String   intercept   = 
                      network . addIntercept ( new   AddInterceptParameters ( InterceptPhase . BEFORE_REQUEST_SENT )); Selenium v4.18 
            const  intercept  =  await  network . addIntercept ( new  AddInterceptParameters ( InterceptPhase . BEFORE_REQUEST_SENT ))  Remove network intercept 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.18 
         try   ( Network   network   =   new   Network ( driver ))   { 
              String   intercept   = 
                      network . addIntercept ( new   AddInterceptParameters ( InterceptPhase . BEFORE_REQUEST_SENT )); 
              Assertions . assertNotNull ( intercept ); 
              network . removeIntercept ( intercept ); Selenium v4.18 
            const  network  =  await  Network ( driver ) 
             const  intercept  =  await  network . addIntercept ( new  AddInterceptParameters ( InterceptPhase . BEFORE_REQUEST_SENT ))  Continue request blocked at authRequired phase with credentials 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.18 
         try   ( Network   network   =   new   Network ( driver ))   { 
              network . addIntercept ( new   AddInterceptParameters ( InterceptPhase . AUTH_REQUIRED )); 
              network . onAuthRequired ( 
                      responseDetails   -> 
                              network . continueWithAuth ( 
                                      responseDetails . getRequest (). getRequestId (), 
                                      new   UsernameAndPassword ( "admin" ,   "admin" ))); 
              driver . get ( "https://the-internet.herokuapp.com/basic_auth" ); Selenium v4.18 
            await  network . addIntercept ( new  AddInterceptParameters ( InterceptPhase . AUTH_REQUIRED )) 
 
             await  network . authRequired ( async  ( event )  =>  { 
                 await  network . continueWithAuth ( event . request . request ,  'admin' , 'admin' ) 
             })  Continue request blocked at authRequired phase without credentials 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.18 
         try   ( Network   network   =   new   Network ( driver ))   { 
              network . addIntercept ( new   AddInterceptParameters ( InterceptPhase . AUTH_REQUIRED )); 
              network . onAuthRequired ( 
                      responseDetails   -> 
                              // Does not handle the alert 
                              network . continueWithAuthNoCredentials ( responseDetails . getRequest (). getRequestId ())); 
              driver . get ( "https://the-internet.herokuapp.com/basic_auth" ); Selenium v4.18 
            await  network . addIntercept ( new  AddInterceptParameters ( InterceptPhase . AUTH_REQUIRED )) 
 
             await  network . authRequired ( async  ( event )  =>  { 
                 await  network . continueWithAuthNoCredentials ( event . request . request ) 
             })  Cancel request blocked at authRequired phase 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.18 
         try   ( Network   network   =   new   Network ( driver ))   { 
              network . addIntercept ( new   AddInterceptParameters ( InterceptPhase . AUTH_REQUIRED )); 
              network . onAuthRequired ( 
                      responseDetails   -> 
                              // Does not handle the alert 
                              network . cancelAuth ( responseDetails . getRequest (). getRequestId ())); 
              driver . get ( "https://the-internet.herokuapp.com/basic_auth" ); Selenium v4.18 
            await  network . addIntercept ( new  AddInterceptParameters ( InterceptPhase . AUTH_REQUIRED )) 
 
             await  network . authRequired ( async  ( event )  =>  { 
                 await  network . cancelAuth ( event . request . request ) 
             })  Fail request 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.18 
         try   ( Network   network   =   new   Network ( driver ))   { 
              network . addIntercept ( new   AddInterceptParameters ( InterceptPhase . BEFORE_REQUEST_SENT )); 
              network . onBeforeRequestSent ( 
                      responseDetails   ->   network . failRequest ( responseDetails . getRequest (). getRequestId ())); 
              driver . manage (). timeouts (). pageLoadTimeout ( Duration . of ( 5 ,   ChronoUnit . SECONDS )); Events This section contains the APIs related to network events.
Before Request Sent 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.15 
         try   ( Network   network   =   new   Network ( driver ))   { 
              CompletableFuture < BeforeRequestSent >   future   =   new   CompletableFuture <> (); 
              network . onBeforeRequestSent ( future :: complete ); 
              driver . get ( "https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html" ); 
 
              BeforeRequestSent   requestSent   =   future . get ( 5 ,   TimeUnit . SECONDS ); Selenium v4.18 
            let  beforeRequestEvent  =  null 
             const  network  =  await  Network ( driver ) 
             await  network . beforeRequestSent ( function  ( event )  { 
                 beforeRequestEvent  =  event 
             }) 
 
             await  driver . get ( 'https://www.selenium.dev/selenium/web/blank.html' )  Response Started 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.15 
         try   ( Network   network   =   new   Network ( driver ))   { 
              CompletableFuture < ResponseDetails >   future   =   new   CompletableFuture <> (); 
              network . onResponseStarted ( future :: complete ); 
              driver . get ( "https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html" ); 
 
              ResponseDetails   response   =   future . get ( 5 ,   TimeUnit . SECONDS ); 
              String   windowHandle   =   driver . getWindowHandle (); Selenium v4.18 
            let  onResponseStarted  =  [] 
             const  network  =  await  Network ( driver ) 
             await  network . responseStarted ( function  ( event )  { 
                 onResponseStarted . push ( event ) 
             }) 
 
             await  driver . get ( 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html' )  Response Completed 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.15 
         try   ( Network   network   =   new   Network ( driver ))   { 
              CompletableFuture < ResponseDetails >   future   =   new   CompletableFuture <> (); 
              network . onResponseCompleted ( future :: complete ); 
              driver . get ( "https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html" ); 
 
              ResponseDetails   response   =   future . get ( 5 ,   TimeUnit . SECONDS ); 
              String   windowHandle   =   driver . getWindowHandle (); Selenium v4.18 
            let  onResponseCompleted  =  [] 
             const  network  =  await  Network ( driver ) 
             await  network . responseCompleted ( function  ( event )  { 
                 onResponseCompleted . push ( event ) 
             }) 
 
             await  driver . get ( 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html' )  Auth Required 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.17 
         try   ( Network   network   =   new   Network ( driver ))   { 
              CompletableFuture < ResponseDetails >   future   =   new   CompletableFuture <> (); 
              network . onAuthRequired ( future :: complete ); 
              driver . get ( "https://the-internet.herokuapp.com/basic_auth" ); 
 
              ResponseDetails   response   =   future . get ( 5 ,   TimeUnit . SECONDS ); 2.4 - Script 
Commands This section contains the APIs related to script commands.
Call function in a browsing context 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.15 
         try   ( Script   script   =   new   Script ( id ,   driver ))   { 
              List < LocalValue >   arguments   =   new   ArrayList <> (); 
              arguments . add ( PrimitiveProtocolValue . numberValue ( 22 )); 
 
              Map < Object ,   LocalValue >   value   =   new   HashMap <> (); 
              value . put ( "some_property" ,   LocalValue . numberValue ( 42 )); 
              LocalValue   thisParameter   =   LocalValue . objectValue ( value ); 
 
              arguments . add ( thisParameter ); 
 
              EvaluateResult   result   = 
                      script . callFunctionInBrowsingContext ( 
                              id , 
                              "function processWithPromise(argument) {\n" 
                                      +   "  return new Promise((resolve, reject) => {\n" 
                                      +   "    setTimeout(() => {\n" 
                                      +   "      resolve(argument + this.some_property);\n" 
                                      +   "    }, 1000)\n" 
                                      +   "  })\n" 
                                      +   "}" , 
                              true , 
                              Optional . of ( arguments ), 
                              Optional . of ( thisParameter ), 
                              Optional . of ( ResultOwnership . ROOT )); Selenium v4.9 
            const  manager  =  await  ScriptManager ( id ,  driver ) 
 
             let  argumentValues  =  [] 
             let  value  =  new  ArgumentValue ( LocalValue . createNumberValue ( 22 )) 
             argumentValues . push ( value ) 
 
             let  mapValue  =  { some_property :  LocalValue . createNumberValue ( 42 )} 
             let  thisParameter  =  new  ArgumentValue ( LocalValue . createObjectValue ( mapValue )). asMap () 
 
             const  result  =  await  manager . callFunctionInBrowsingContext ( 
                 id , 
                 'function processWithPromise(argument) {'  + 
                 'return new Promise((resolve, reject) => {'  + 
                 'setTimeout(() => {'  + 
                 'resolve(argument + this.some_property);'  + 
                 '}, 1000)'  + 
                 '})'  + 
                 '}' , 
                 true , 
                 argumentValues , 
                 thisParameter , 
                 ResultOwnership . ROOT )  Call function in a sandbox 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.15 
         try   ( Script   script   =   new   Script ( id ,   driver ))   { 
              EvaluateResult   result   = 
                      script . callFunctionInBrowsingContext ( 
                              id , 
                              "sandbox" , 
                              "() => window.foo" , 
                              true , 
                              Optional . empty (), 
                              Optional . empty (), 
                              Optional . empty ()); Selenium v4.9 
            const  manager  =  await  ScriptManager ( id ,  driver ) 
 
             await  manager . callFunctionInBrowsingContext ( id ,  '() => { window.foo = 2; }' ,  true ,  null ,  null ,  null ,  'sandbox' )  Call function in a realm 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.15 
         try   ( Script   script   =   new   Script ( tab ,   driver ))   { 
              List < RealmInfo >   realms   =   script . getAllRealms (); 
              String   realmId   =   realms . get ( 0 ). getRealmId (); 
 
              EvaluateResult   result   =   script . callFunctionInRealm ( 
                      realmId , 
                      "() => { window.foo = 3; }" , 
                      true , 
                      Optional . empty (), 
                      Optional . empty (), 
                      Optional . empty ()); Selenium v4.9 
            const  manager  =  await  ScriptManager ( firstTab ,  driver ) 
 
             const  realms  =  await  manager . getAllRealms () 
             const  realmId  =  realms [ 0 ]. realmId 
 
             await  manager . callFunctionInRealm ( realmId ,  '() => { window.foo = 3; }' ,  true )  Evaluate script in a browsing context 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.15 
         try   ( Script   script   =   new   Script ( id ,   driver ))   { 
              EvaluateResult   result   = 
                      script . evaluateFunctionInBrowsingContext ( id ,   "1 + 2" ,   true ,   Optional . empty ()); 
 Selenium v4.9 
            const  manager  =  await  ScriptManager ( id ,  driver ) 
 
             const  result  =  await  manager . evaluateFunctionInBrowsingContext ( id ,  '1 + 2' ,  true )  Evaluate script in a sandbox 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.15 
         try   ( Script   script   =   new   Script ( id ,   driver ))   { 
              EvaluateResult   result   = 
                      script . evaluateFunctionInBrowsingContext ( 
                              id ,   "sandbox" ,   "window.foo" ,   true ,   Optional . empty ()); Selenium v4.9 
            const  manager  =  await  ScriptManager ( id ,  driver ) 
 
             await  manager . evaluateFunctionInBrowsingContext ( id ,  'window.foo = 2' ,  true ,  null ,  'sandbox' ) 
 
             const  resultInSandbox  =  await  manager . evaluateFunctionInBrowsingContext ( id ,  'window.foo' ,  true ,  null ,  'sandbox' )  Evaluate script in a realm 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.15 
         try   ( Script   script   =   new   Script ( tab ,   driver ))   { 
              List < RealmInfo >   realms   =   script . getAllRealms (); 
              String   realmId   =   realms . get ( 0 ). getRealmId (); 
 
              EvaluateResult   result   = 
                      script . evaluateFunctionInRealm ( 
                              realmId ,   "window.foo" ,   true ,   Optional . empty ()); Selenium v4.9 
            const  manager  =  await  ScriptManager ( firstTab ,  driver ) 
 
             const  realms  =  await  manager . getAllRealms () 
             const  realmId  =  realms [ 0 ]. realmId 
 
             await  manager . evaluateFunctionInRealm ( realmId ,  'window.foo = 3' ,  true ) 
 
             const  result  =  await  manager . evaluateFunctionInRealm ( realmId ,  'window.foo' ,  true )  Disown handles in a browsing context 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.15 
             script . disownBrowsingContextScript ( Selenium v4.9 
            await  manager . disownBrowsingContextScript ( id ,  boxId )  Disown handles in a realm 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.15 
             script . disownRealmScript ( realmId ,   List . of ( boxId )); Selenium v4.9 
            await  manager . disownRealmScript ( realmId ,  boxId )  Get all realms 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.15 
         try   ( Script   script   =   new   Script ( firstWindow ,   driver ))   { 
              List < RealmInfo >   realms   =   script . getAllRealms (); Selenium v4.9 
            const  manager  =  await  ScriptManager ( firstWindow ,  driver ) 
 
             const  realms  =  await  manager . getAllRealms ()  Get realm by type 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.15 
         try   ( Script   script   =   new   Script ( firstWindow ,   driver ))   { 
              List < RealmInfo >   realms   =   script . getRealmsByType ( RealmType . WINDOW ); Selenium v4.9 
            const  manager  =  await  ScriptManager ( firstWindow ,  driver ) 
 
             const  realms  =  await  manager . getRealmsByType ( RealmType . WINDOW )  Get browsing context realms 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.15 
         try   ( Script   script   =   new   Script ( windowId ,   driver ))   { 
              List < RealmInfo >   realms   =   script . getRealmsInBrowsingContext ( tabId ); Selenium v4.9 
            const  manager  =  await  ScriptManager ( windowId ,  driver ) 
 
             const  realms  =  await  manager . getRealmsInBrowsingContext ( tabId )  Get browsing context realms by type 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.15 
             List < RealmInfo >   windowRealms   = 
                      script . getRealmsInBrowsingContextByType ( windowId ,   RealmType . WINDOW ); Selenium v4.9 
            const  realms  =  await  manager . getRealmsInBrowsingContextByType ( windowId ,  RealmType . WINDOW )  Preload a script 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.15 
             String   id   =   script . addPreloadScript ( "() => { window.bar=2; }" ,   "sandbox" ); Selenium v4.10 
            const  manager  =  await  ScriptManager ( id ,  driver ) 
 
             const  scriptId  =  await  manager . addPreloadScript ( '() => {{ console.log(\'{preload_script_console_text}\') }}' )  Remove a preloaded script 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.15 
                 script . removePreloadScript ( id ); Selenium v4.10 
            await  manager . removePreloadScript ( scriptId )  Events This section contains the APIs related to script events.
Message 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.16 
         try   ( Script   script   =   new   Script ( driver ))   { 
              CompletableFuture < Message >   future   =   new   CompletableFuture <> (); 
              script . onMessage ( future :: complete ); 
 
              script . callFunctionInBrowsingContext ( 
                      driver . getWindowHandle (), 
                      "(channel) => channel('foo')" , 
                      false , 
                      Optional . of ( List . of ( LocalValue . channelValue ( "channel_name" ))), 
                      Optional . empty (), 
                      Optional . empty ()); 
 
              Message   message   =   future . get ( 5 ,   TimeUnit . SECONDS ); 
              Assertions . assertEquals ( "channel_name" ,   message . getChannel ()); 
          } Selenium v4.18 
            const  manager  =  await  ScriptManager ( undefined ,  driver ) 
 
             let  message  =  null 
 
             await  manager . onMessage (( m )  =>  { 
                 message  =  m 
             }) 
 
             let  argumentValues  =  [] 
             let  value  =  new  ArgumentValue ( LocalValue . createChannelValue ( new  ChannelValue ( 'channel_name' ))) 
             argumentValues . push ( value ) 
 
             const  result  =  await  manager . callFunctionInBrowsingContext ( 
                 await  driver . getWindowHandle (), 
                 '(channel) => channel("foo")' , 
                 false , 
                 argumentValues , 
             )  Realm Created 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.16 
         try   ( Script   script   =   new   Script ( driver ))   { 
              CompletableFuture < RealmInfo >   future   =   new   CompletableFuture <> (); 
              script . onRealmCreated ( future :: complete ); 
 
              BrowsingContext   context   =   new   BrowsingContext ( driver ,   driver . getWindowHandle ()); 
 
              context . navigate ( "https://www.selenium.dev/selenium/blankPage" ); 
              RealmInfo   realmInfo   =   future . get ( 5 ,   TimeUnit . SECONDS ); 
              Assertions . assertNotNull ( realmInfo . getRealmId ()); 
              Assertions . assertEquals ( RealmType . WINDOW ,   realmInfo . getRealmType ()); 
          } Selenium v4.18 
            const  manager  =  await  ScriptManager ( undefined ,  driver ) 
 
             let  realmInfo  =  null 
 
             await  manager . onRealmCreated (( result )  =>  { 
                 realmInfo  =  result 
             }) 
 
             const  id  =  await  driver . getWindowHandle () 
             const  browsingContext  =  await  BrowsingContext ( driver ,  { 
                 browsingContextId :  id , 
             }) 
 
             await  browsingContext . navigate ( 'https://www.selenium.dev/selenium/web/blank' ,  'complete' )  Realm Destroyed 
Java 
Ruby 
JavaScript 
Kotlin Selenium v4.16 
         try   ( Script   script   =   new   Script ( driver ))   { 
              CompletableFuture < RealmInfo >   future   =   new   CompletableFuture <> (); 
              script . onRealmDestroyed ( future :: complete ); 
 
              BrowsingContext   context   =   new   BrowsingContext ( driver ,   driver . getWindowHandle ()); 
 
              context . close (); 
              RealmInfo   realmInfo   =   future . get ( 5 ,   TimeUnit . SECONDS ); 
              Assertions . assertNotNull ( realmInfo . getRealmId ()); 
              Assertions . assertEquals ( RealmType . WINDOW ,   realmInfo . getRealmType ()); 
          } Selenium v4.19 
            const  manager  =  await  ScriptManager ( undefined ,  driver ) 
 
             let  realmInfo  =  null 
 
             await  manager . onRealmDestroyed (( result )  =>  { 
                 realmInfo  =  result 
             }) 
 
             const  id  =  await  driver . getWindowHandle () 
             const  browsingContext  =  await  BrowsingContext ( driver ,  { 
                 browsingContextId :  id , 
             }) 
 
             await  browsingContext . close ()  2.5 - BiDirectional API (W3C compliant) 
This section contains the APIs related to logging.
Console logs Listen to the console.log events and register callbacks to process the event.
Java 
Ruby 
JavaScript 
Kotlin      public   void   jsErrors ()   { 
          CopyOnWriteArrayList < ConsoleLogEntry >   logs   =   new   CopyOnWriteArrayList <> (); 
 
          try   ( LogInspector   logInspector   =   new   LogInspector ( driver ))   { 
              logInspector . onConsoleEntry ( logs :: add ); 
          } 
 
          driver . get ( "https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html" ); Selenium v4.8 
            const  inspector  =  await  LogInspector ( driver ) 
             await  inspector . onConsoleEntry ( function  ( log )  { 
                 logEntry  =  log 
             }) 
 
             await  driver . get ( 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html' ) 
             await  driver . findElement ({ id :  'consoleLog' }). click () 
 
             assert . equal ( logEntry . text ,  'Hello, world!' ) 
             assert . equal ( logEntry . realm ,  null ) 
             assert . equal ( logEntry . type ,  'console' ) 
             assert . equal ( logEntry . level ,  'info' ) 
             assert . equal ( logEntry . method ,  'log' ) 
             assert . equal ( logEntry . stackTrace ,  null ) 
             assert . equal ( logEntry . args . length ,  1 )  JavaScript exceptions Listen to the JS Exceptions
and register callbacks to process the exception details.
Java 
Ruby 
JavaScript 
Kotlin              logInspector . onJavaScriptLog ( future :: complete ); 
 
              driver . get ( "https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html" ); 
              driver . findElement ( By . id ( "jsException" )). click (); 
 
              JavascriptLogEntry   logEntry   =   future . get ( 5 ,   TimeUnit . SECONDS ); 
 
              Assertions . assertEquals ( "Error: Not working" ,   logEntry . getText ()); Selenium v4.8 
            const  inspector  =  await  LogInspector ( driver ) 
             await  inspector . onJavascriptException ( function  ( log )  { 
                 logEntry  =  log 
             }) 
 
             await  driver . get ( 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html' ) 
             await  driver . findElement ({ id :  'jsException' }). click () 
 
             assert . equal ( logEntry . text ,  'Error: Not working' ) 
             assert . equal ( logEntry . type ,  'javascript' ) 
             assert . equal ( logEntry . level ,  'error' )  Listen to JS Logs Listen to all JS logs at all levels and register callbacks to process the log.
Java 
Ruby 
JavaScript 
Kotlin              driver . findElement ( By . id ( "consoleLog" )). click (); 
 
              ConsoleLogEntry   logEntry   =   future . get ( 5 ,   TimeUnit . SECONDS ); 
 
              Assertions . assertEquals ( "Hello, world!" ,   logEntry . getText ()); 
              Assertions . assertNull ( logEntry . getRealm ()); 
              Assertions . assertEquals ( 1 ,   logEntry . getArgs (). size ()); 
              Assertions . assertEquals ( "console" ,   logEntry . getType ());